Как я могу избежать использования переменных класса в 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 Выборы нового президента, например.

Другие вопросы по тегам