Как я могу избежать использования переменных класса в Ruby
У меня есть кусок кода, который использует переменные класса. Я читал, что в Ruby следует избегать переменных класса.
Переменные класса @@cost
а также @@kwh
,
Как я могу переписать следующее без использования переменных класса?
class Device
attr_accessor :name, :watt
@@cost = 0.0946
def initialize(name, watt)
@name = name
@watt = watt
end
def watt_to_kwh(hours)
@@kwh = (watt / 1000) * hours
end
def cost_of_energy
puts "How many hours do you use the #{self.name} daily?"
hours = gets.chomp.to_i
self.watt_to_kwh(hours)
daily_cost = @@kwh * @@cost
montly_cost = daily_cost * 30
puts "Dayly cost: #{daily_cost}€"
puts "montly_cost: #{montly_cost}€"
end
end
2 ответа
@@cost
ведет себя больше как константа (т.е. она не изменится во время выполнения), поэтому вы должны использовать ее вместо:
COST = 0.0946
@@kwh
должна быть переменной экземпляра, поскольку она используется только внутри экземпляра объекта, поэтому вы можете использовать @kwh
вместо:
@kwh = (watt / 1000) * hours
А также daily_cost = @@kwh * @@cost
станет:
daily_cost = @kwh * COST
Это позволит избежать использования переменных класса, но вы также можете устранить @kwh
вообще, так как вы не используете его где-либо еще.
Итак, вместо:
def watt_to_kwh(hours)
@kwh = (watt / 1000) * hours
end
Вы могли бы просто сделать:
def watt_to_kwh(hours)
(watt / 1000) * hours
end
И использовать это так в cost_of_energy
метод:
def cost_of_energy
puts "How many hours do you use the #{self.name} daily?"
hours = gets.chomp.to_i
daily_cost = watt_to_kwh(hours) * COST
montly_cost = daily_cost * 30
puts "Dayly cost: #{daily_cost}€"
puts "montly_cost: #{montly_cost}€"
end
Попробуй это.
class Device
singleton_class.send(:attr_accessor, :cost_per_kwh)
def initialize(name, watts)
@name = name
@watts = watts
end
def daily_cost(hours_per_day)
self.class.cost_per_kwh * kwh_per_day(hours_per_day)
end
def monthly_cost(hours_per_day)
30 * daily_cost(hours_per_day)
end
private
def kwh_per_day(hours_per_day)
hours_per_day * @watts / 1000
end
end
singleton_class.send(:attr_accessor, :cost_per_kwh)
создает сеттер и геттер для переменной экземпляра класса @cost_per_kwh
,
Во-первых, получите и сохраните стоимость за киловатт-час, которая будет использоваться при расчете стоимости для всех интересующих устройств.
puts "Please enter the cost per kwh in $"
Device.cost_per_kwh = gets.chomp.to_f
предполагать
Device.cost_per_kwh = 0.0946
Рассчитайте стоимость каждого интересующего устройства.
puts "What is the name of the device?"
name = gets.chomp
puts "How many watts does it draw?"
watts = gets.chomp.to_f
предполагать
name = "chair"
watts = 20000.0
Теперь мы можем создать экземпляр класса.
device = Device.new(name, watts)
#=> #<Device:0x007f9d530206f0 @name="chair", @watts=20000.0>
Наконец, получите часы в сутки, единственную переменную, которая может измениться в будущих расчетах затрат для данного устройства.
puts "How many hours do you use the #{name} daily?"
hours_per_day = gets.chomp.to_f
Наконец, предположим,
hours_per_day = 0.018
тогда мы можем рассчитать стоимость.
puts "Daily cost: $#{ device.daily_cost(hours_per_day)}"
Daily cost: $0.034056€
puts "Monthly_cost (30 days/month): $#{ 30 * device.daily_cost(hours_per_day) }"
Monthly_cost (30 days/month): $1.0216800000000001
Предположим, что обстоятельства меняются1 и использование устройства увеличивается. Нам нужно только обновлять часы в день. Например,
puts "How many hours do you use the #{name} daily?"
hours_per_day = gets.chomp.to_f
Предположим сейчас
hours_per_day = 1.5
затем
puts "Daily cost: $#{ device.daily_cost(hours_per_day)}"
Daily cost: $2.838
puts "Monthly_cost (30 days/month): $#{ 30 * device.daily_cost(hours_per_day) }"
Monthly_cost (30 days/month): $85.14
1 Выборы нового президента, например.