statische Variablen in Ruby

70

Ich habe gerade etwas über statische Variablen in PHP gelernt. Gibt es so etwas in Rubin?

Wenn wir beispielsweise eine StudentKlasse erstellen möchten und für jedes studentObjekt, das wir erstellen, sollte die ID-Nummer automatisch erhöht werden.

Ich dachte, das Erstellen einer Klassenvariablen als statische Variable reicht aus.

Levirg
quelle
@ Andrew Es wird nicht erwähnt, dass eine Datenbank vorhanden ist.
Oddmund
@Oddmund Ich nahm an, dass das OP deshalb eine ID-Nummer wollte.
Andrew Grimm

Antworten:

109

Klassenvariablen werden von allen Instanzen gemeinsam genutzt (weshalb sie als Klassenvariablen bezeichnet werden), sodass sie das tun, was Sie wollen. Sie werden auch vererbt, was manchmal zu verwirrendem Verhalten führt, aber ich denke nicht, dass dies hier ein Problem sein wird. Hier ist ein Beispiel für eine Klasse, die eine Klassenvariable verwendet, um zu zählen, wie viele Instanzen davon erstellt wurden:

class Foo
  @@foos = 0

  def initialize
    @@foos += 1
  end

  def self.number_of_foos
    @@foos
  end
end

Foo.new
Foo.new
Foo.number_of_foos #=> 2
sepp2k
quelle
Danke Mann ... Ich habe etwas Idiotisches in meinem Code getan und das Konzept völlig missverstanden ...
Levirg
-1 Ihr Beispiel hat einen Nachteil, foos from @@foos = 0ist nicht dieselbe Variable wie die anderen beiden, es ist eine Klassenvariable der Klasse Class(Foo ist eine Instanz der Klasse Class). Ich werde die Abwertung entfernen, wenn Sie sie korrigieren .
Clyfe
6
@ Clyfe: Du liegst falsch. Sie verwechseln Klassenvariablen mit Instanzvariablen. Dabei wird class Foo; @@foo = "foo" enddie Klassenvariable @@foofür Foo und nicht für Class festgelegt. Probieren Sie es aus: class Foo; @@foo = 1 end; class Object; @@foo endwird eine produzieren NameError: uninitialized class variable @@foo in Class.
sepp2k
2
@ Khelll: Nicht unvorhersehbar, unerwartet. Das Verhalten von Klassenvariablen ist vollständig deterministisch.
sepp2k
1
@ Khell: Was ist damit? Ich habe bereits erwähnt, dass Klassenvariablen geerbt werden. Ich sagte auch, dass dies zu verwirrendem Verhalten führt. Trotzdem gibt dieser Code jedes Mal das gleiche Ergebnis zurück, wenn Sie ihn ausführen. Und selbst wenn Sie nicht erwähnt hätten, dass es 2 zurückgibt, hätte ich gewusst, dass es 2 zurückgibt, ohne es auszuführen, also ist es eindeutig deterministisch.
sepp2k
15

Die Verwendung der akzeptierten Antwort als Definition der statischen Variablen kann gefährlich sein, und es ist ein häufiger Fehler, den ich in vielen Ruby-Codes gesehen habe.

So etwas @@fooswird von ALLEN Unterklassen geteilt. Die meisten Programmierer erwarten jedoch, dass statische Variablen nur innerhalb der Klasse Gültigkeitsbereich haben, in der sie definiert sind.

Wenn Sie nach statischen Variablen im Sinne der meisten Sprachen suchen, deren Gültigkeitsbereich nur ihre eigene Klasse ist, sehen Sie sich diese SO-Antwort an

Auch dieser Blog-Beitrag enthält ein schönes Beispiel für die Überraschung, die die meisten Programmierer erleben werden:

http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

SystematicFrank
quelle
3
Tatsächlich werden Sie überrascht sein, wie viele Personen mit falschen Vorstellungen erwarten, dass die statische Aufladung auf alle Unterklassen in anderen Sprachen verteilt wird: P
Rael Gugelmin Cunha,