Search code examples
rubyclass-variables

How can I avoid using class variables in Ruby


I have a piece of code that uses class variables. I've read that class variables should generally be avoided in Ruby.

The class variables are @@cost and @@kwh.

How can I rewrite the following without using class variables?

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

Solution

  • @@cost behaves more like a constant (i.e. it won't change during runtime), so you should use one instead:

    COST = 0.0946
    

    @@kwh should be an instance variable, since it is used only within the instantiated object, so you could use @kwh instead:

    @kwh = (watt / 1000) * hours
    

    And daily_cost = @@kwh * @@cost will become:

    daily_cost = @kwh * COST
    

    That will avoid the use of class variables, but you could also eliminate @kwh altogether since you don't use it anywhere else.

    So, instead of:

    def watt_to_kwh(hours)
      @kwh = (watt / 1000) * hours
    end
    

    You could just do:

    def watt_to_kwh(hours)
      (watt / 1000) * hours
    end
    

    And use it like this in cost_of_energy method:

    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