2017-06-11 2 views
0

Ich habe ein Stück Code, der Klassenvariablen verwendet. Ich habe gelesen, dass Klassenvariablen generell in Ruby vermieden werden sollten.Wie kann ich vermeiden, Klassenvariablen in Ruby zu verwenden

Die Klassenvariablen sind @@cost und @@kwh.

Wie kann ich Folgendes ohne Klassenvariablen umschreiben?

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

Warum ist '@@ kwh' eine Klassenvariable? –

+1

Ich glaube 'montly_cost' sollte' monty_cost' sein, vorausgesetzt es handelt sich um Monty Pythons Flying Circus. –

Antwort

4

@@cost verhält sich eher wie ein Konstante (dh es wird nicht während der Laufzeit ändern), so dass Sie einen stattdessen verwenden sollten:

COST = 0.0946 

@@kwh sollte eine Instanz variabel sein, da es nur innerhalb des instanziierten Objekt verwendet, so könnte man @kwh statt:

@kwh = (watt/1000) * hours 

Und daily_cost = @@kwh * @@cost wird worden:

daily_cost = @kwh * COST 

, dass die Verwendung von Klassenvariablen werden vermeiden, aber man könnte auch @kwh zusammen beseitigen, da Sie es nicht irgendwo anders verwenden.

Anstatt also:

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

könnten Sie gerade tun:

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

Und es wie folgt in cost_of_energy Methode verwenden:

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

Ich habe eigentlich beide Instanz Variablen vor dem Posten, aber es hat nicht funktioniert, ich bekam ein '* ': Nil kann nicht in Integer' TypeError umgewandelt werden. Jetzt sehe ich, dass 'Cost' eine lokale Variable ist der Grund, warum ich den Fehler bekomme. Aber warum? Warum funktioniert '@ kwh' und' @kosten' nicht? – johnlock1

+1

@ johnlock1 Wie hast du '@cost = 0.0946' gesetzt? Es sollte innerhalb der 'initialize' Methode (oder einer anderen Instanzmethode) gesetzt werden. – Gerry

+0

@gery Ok, um eine Instanzvariable zu verwenden, muss ich sie innerhalb einer Methode setzen? Ich habe das nicht verstanden, danke, dass du es für mich erledigt hast! – johnlock1

1

bereits.

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) schafft eine Setter und Getter für die Klasseninstanzvariable @cost_per_kwh.

Zuerst erhalten und speichern Sie die Kosten pro kwh, die bei der Berechnung der Kosten für alle Geräte von Interesse verwendet werden.

puts "Please enter the cost per kwh in $"  
Device.cost_per_kwh = gets.chomp.to_f 

Angenommen

Device.cost_per_kwh = 0.0946 

Berechnen Sie die Kosten für jedes Gerät von Interesse.

puts "What is the name of the device?" 
name = gets.chomp 

puts "How many watts does it draw?" 
watts = gets.chomp.to_f 

Angenommen

name = "chair" 
watts = 20000.0 

Wir können nun eine Instanz der Klasse erstellen.

Schließlich, erhalten Stunden pro Tag, die einzige Variable, die sich wahrscheinlich in zukünftigen Berechnungen der Kosten für das gegebene Gerät ändern wird.

puts "How many hours do you use the #{name} daily?" 
hours_per_day = gets.chomp.to_f 

Schließlich nehme

hours_per_day = 0.018 

dann können wir die Kosten berechnen.

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 

Angenommen Umstände ändern 1 und die Verwendung der Vorrichtung zunimmt. Wir müssen nur die Stunden pro Tag aktualisieren. Zum Beispiel

puts "How many hours do you use the #{name} daily?" 
hours_per_day = gets.chomp.to_f 

Es sei nun angenommen

hours_per_day = 1.5 

Dann

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 Die Wahl eines neuen Präsidenten, zum Beispiel.

+0

Schön! Ich mag 'singleton_class', um die (hartcodierte) Konstante zu vermeiden. – Gerry

Verwandte Themen