2017-06-11 7 views
0

クラス変数を使用するコードがあります。私は、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 
+0

なぜ '@@ kwh'はクラス変数ですか? –

+1

私は 'montly_cost'は' monty_cost'とすべきだと考えています。それはMonty PythonのFlying Circusに関するものと仮定しています。 –

答えて

4

@@costは、より多くのように振る舞う定数(すなわち、それは実行時に変更されることはありません)あなたの代わりに1を使用する必要がありますので、:

COST = 0.0946 

@@kwhはインスタンス変数である必要があり、それがあることから、インスタンス化されたオブジェクト内でのみ使用されるため、

@kwh = (watt/1000) * hours 

および0123の代わりに@kwhを使用できます。はなります:クラス変数の使用を避けることができますが、あなたはどこにもそれを使用していないので、あなたはまた、完全@kwhを排除することができる

daily_cost = @kwh * COST 

。だから、

、代わりに:

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

あなただけ行うことができます:

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

そして​​方法でこのようにそれを使用します。

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 
+0

私は実際に両方のインスタンス変数を投稿する前に投稿しましたが、うまくいきませんでした。私は '* 'を得ていました:nilはInteger' TypeErrorに強制できません。 これで、 'Cost'をローカル変数にするのは、エラーが出る理由です。しかし、なぜ?なぜ '@ kwh'が動作し、' @ cost'が動作しないのですか? – johnlock1

+1

@ johnlock1 '@cost = 0.0946'をどうやって設定しましたか?これは 'initialize'メソッド(または他のインスタンスメソッド)の中で設定する必要があります。 – Gerry

+0

@geryさて、インスタンス変数を使用するには、メソッド内に設定する必要がありますか?私はそれを理解していない、私のためにそれをクリアするためのおかげで! – johnlock1

1

はこれを試してみてください。

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用セッターとゲッターを作成します。

まず、関心のあるすべてのデバイスのコスト計算に使用される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例えば新大統領の選挙。

+0

ニース!私は(ハードコードされた)定数を避けるために 'singleton_class'が好きです。 – Gerry

関連する問題