Hier ist der Code, außer ich die Klassenmethode in der üblichen Weise definiert habe (def self.speak...
). Da eine Klassenmethode nichts anderes als eine Instanzmethode ist, die für die Singleton-Klasse der Klasse definiert ist, ist diese Änderung lediglich eine andere Möglichkeit, dieselbe Klassenmethode zu erstellen. (Wenn Sie das bezweifeln, führen Sie den Code in beiden Richtungen aus.) Ich habe diese Änderung vorgenommen, weil ich dachte, dass dies meine Erklärung des Geschehens klarer machen würde. Ich fügte auch eine puts
Erklärung hinzu.
class Speaker
@message = "Hello!"
def self.speak
puts "self=#{self}"
@message
end
class << self
@message = "Howdy!"
end
end
Die erste Zeile der Klassendefinition erstellt eine Klasseninstanzvariable @message
:
Speaker.instance_variables
#=> [:@message]
Speaker.instance_variable_get(:@message)
#=> "Hello!"
von constrast,
@message = "Howdy!"
eine Instanzvariable auf Speaker
‚s Singletonklasse erstellt:
Speaker.singleton_class.instance_variables
#=> [:@message]
Speaker.singleton_class.instance_variable_get(:@message)
#=> "Howdy!"
aufrufen Jetzt speak
auf Speaker
:
Speaker.speak
# self=Speaker
#=> "Hello!"
Als self #=> Speaker
, speak
offensichtlich den Wert der Klasse Instanzvariablen zurück.
Für speak
den Wert der Instanzvariablen auf Speaker
‚s Singletonklasse definiert zurückzukehren wir folgendes schreiben:
class Speaker
@message = "Hello!"
def self.speak
puts "self=#{self}"
puts "singleton_class = #{singleton_class}"
singleton_class.instance_variable_get :@message
end
class << self
@message = "Howdy!"
end
end
puts Speaker.speak
# self=Speaker
# singleton_class = #<Class:Speaker>
# Howdy!
Im letzten Ausdruck, weil self
Speaker
gleich und self
ist die implizite Empfänger, wenn Es gibt keinen expliziten Empfänger, "singleton_class
entspricht Speaker.singleton_class
.
'@ message' oben ist eine Instanzvariable auf Klassenebene, sie gehört zur Klasse' Speaker', die selbst als Objekt eine Instanz der Klasse 'Class' ist:' Speaker.class # => Class', 'Speaker .instance_variables # => [: @message] ' –