Allgemeine Ruby Frage: In Ruby sehe ich häufig Code innerhalb einer Klasse, aber nicht Teil einer Methode. Zum Beispiel:
%Vor%oder
%Vor% Ich denke attr_accessor
und has_many
sind Methoden, die mit den :foo
bzw. :students
Argumenten aufgerufen werden, ist das richtig? Wenn ja, wann werden diese Arten von Anweisungen ausgeführt. Ich habe es versucht:
Es scheint nicht, dass diese einen Teil der Methode new
ausführen:
gibt nil aus und spuckt niemals puts
stuff aus
Wie genau funktioniert das alles?
Methoden wie attr_accessor
und has_many
werden oft als "mimische Methoden" bezeichnet, da sie wie Ruby-Schlüsselwörter aussehen (sie nachahmen), aber sie sind tatsächlich, wie Sie und andere richtig bemerkt haben, Methodenaufrufe / p>
%Vor%
gibt nil aus und spuckt niemals
puts
stuff ausWie genau funktioniert das alles?
Wenn Sie innerhalb einer Klassendefinition sind, ist der implizite Empfänger aller Methodenaufrufe und "Variablendefinitionen" self
, was in Ihrem Fall DooDad
ist.
Also wenn du schreibst
%Vor% Sie definieren tatsächlich eine Instanzvariable in self
, die zufällig die Klasse selbst ist, da Sie innerhalb dieser Klassendefinition sind. (und außerhalb anderer Klassen-, Modul- oder Methodendefinitionen)
Die Methode attr_accessor
hingegen erzeugt mit Hilfe der Metaprogrammierung Zugriffsmethoden für eine Instanzvariable der Objekte, die aus der Klasse DooDad
instanziiert werden.
Zurück zu Ihrem Beispiel:
%Vor% Mit den oben erwähnten Dingen sollten Sie jetzt verstehen, dass Sie es mit zwei verschiedenen @ foo-Variablen zu tun haben, eine für Instanzen der Klasse DooDad (dh DooDad.new
), die andere (die Sie mit @foo = 7
erstellt haben) ) für die Klasse DooDad selbst!
Wenn Sie die Methode new
für eine Klasse aufrufen, erstellen Sie eine Instanz davon.
Die Anweisung puts "I happened!"
wird genau wie die anderen beiden tatsächlich ausgewertet, sobald die Klasse geladen wird, aber nicht, wenn Sie new
darauf aufrufen.
Wenn Sie das Verhalten haben wollen, das Sie beschrieben haben (indem Sie new
aufrufen), empfehle ich die Implementierung einer initialize()
-Methode für DooDad
, die beim Aufruf von new
aufgerufen wird:
Aber warum setzt @foo = 7
jetzt die Instanzvariable von dd
und nicht von DooDad
?
Wenn Sie eine Methode mit dem Schlüsselwort def
definieren, geben Sie einen neuen Bereich ein (Sie übergeben ein Scope Gate). self
ist jetzt nicht mehr die Klasse, sondern eine Instanz der Klasse, die Sie mit new
erstellt haben, genau wie dd
. Wenn Sie @foo = 7
innerhalb einer Methodendefinition schreiben, sprechen Sie also von Variablen für eine Instanz der Klasse DooDad
, nicht von der Klasse selbst.
Dieser Beitrag ist wahrscheinlich viel zu lang und könnte nicht einmal als Antwort genügen, aber ich hoffe, er war etwas umfassend.
Methoden wie has_many
und attr_accessor
sind tatsächlich Methoden des Moduls oder der Klasse. Sie haben absolut Recht damit, dass sie normale Methoden sind, die mit Argumenten wie jeder andere aufgerufen werden. Wenn eine Methode direkt in der Klasse aufgerufen wird (außerhalb einer Methodendefinition), wird sie in der Klasse selbst aufgerufen.
Hier sind die Dokumente für attr_accessor .
Tags und Links ruby