Was genau ist die Singleton-Klasse in Ruby?
Frage
Ist die Singleton-Klasse in Ruby eine Klasse an und für sich? Ist es der Grund, warum alle Objekte zu gehören „Klasse?“ Das Konzept ist Fuzzy , aber ich glaube, es hat etwas mit dem zu tun, warum ich eine Klassenmethode bei allen (class foo; def foo.bar ...
) definieren kann.
Was ist die Singleton-Klasse in Ruby?
Lösung
Zuerst eine wenig Definition: a Singleton-Methode ist eine Methode, die nur für ein einzelnes Objekt definiert ist. Beispiel:
irb(main):001:0> class Foo; def method1; puts 1; end; end
=> nil
irb(main):002:0> foo = Foo.new
=> #<Foo:0xb79fa724>
irb(main):003:0> def foo.method2; puts 2; end
=> nil
irb(main):004:0> foo.method1
1
=> nil
irb(main):005:0> foo.method2
2
=> nil
irb(main):006:0> other_foo = Foo.new
=> #<Foo:0xb79f0ef4>
irb(main):007:0> other_foo.method1
1
=> nil
irb(main):008:0> other_foo.method2
NoMethodError: undefined method `method2' for #<Foo:0xb79f0ef4>
from (irb):8
Instance Methoden sind Methoden einer Klasse (das heißt in der Klassendefinition definiert sind). Klassenmethoden sind Singleton-Methoden auf der Class
Instanz einer Klasse - sie sind nicht in der Klasse Definition definiert. Stattdessen werden sie auf der Seite Singletonklasse definiert des Objekts.
irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false
Sie öffnen die Singleton-Klasse eines Objekts mit der Syntax class << obj
. Hier sehen wir, dass diese Singletonklasse ist, wo die Singleton-Methoden definiert werden:
irb(main):012:0> singleton_class = ( class << foo; self; end )
=> #<Class:#<Foo:0xb79fa724>>
irb(main):013:0> singleton_class.method_defined? :method1
=> true
irb(main):014:0> singleton_class.method_defined? :method2
=> true
irb(main):015:0> other_singleton_class = ( class << other_foo; self; end )
=> #<Class:#<Foo:0xb79f0ef4>>
irb(main):016:0> other_singleton_class.method_defined? :method1
=> true
irb(main):017:0> other_singleton_class.method_defined? :method2
=> false
So ein alternatives Mittel zur Zugabe von Singleton-Methoden auf ein Objekt sei, um sie mit dem Singleton-Klasse des Objekts zu definieren offen:
irb(main):018:0> class << foo; def method3; puts 3; end; end
=> nil
irb(main):019:0> foo.method3
3
=> nil
irb(main):022:0> Foo.method_defined? :method3
=> false
Zusammenfassung:
- Methoden müssen immer zu einer Klasse gehören (oder: Instanzmethoden einer Klasse sein)
- normale Methoden gehören zu der Klasse, die sie in definiert sind (das heißt sind Instanzmethoden der Klasse)
- Klassenmethoden sind nur Singleton-Methoden eines
Class
- Singleton-Methoden eines Objekts sind nicht Instanzmethoden der Klasse des Objekts; vielmehr sind sie Instanzmethoden der Singleton-Klasse des Objekts.
Andere Tipps
Ruby-Verfahren bietet eine Möglichkeit zu definieren, die auf ein bestimmtes Objekt spezifisch sind, und solche Verfahren, wie Singleton-Methoden sind bekannt. Wenn man eine Singleton-Methode auf einem Objekt deklariert, erstellt Rubin automatisch eine Klasse nur die Singleton-Methoden zu halten. Die neu geschaffene Klasse Singleton Klasse genannt.
foo = Array.new
def foo.size
"Hello World!"
end
foo.size # => "Hello World!"
foo.class # => Array
#Create another instance of Array Class and call size method on it
bar = Array.new
bar.size # => 0
Singleton-Klasse spezifisch ist anonyme Klasse Objekt, das automatisch erstellt wird und in die Vererbungshierarchie eingefügt.
singleton_methods
kann auf einem Objekt aufgerufen werden, für alle die Singleton-Methoden auf einem Objekt die Liste der Namen zu erhalten.
foo.singleton_methods # => [:size]
bar.singleton_methods # => []
Die Artikel hat mir wirklich geholfen Singleton-Klassen in Ruby zu verstehen, und es hat einen guten Code Beispiel.
Wie aktualisieren Sie einfach auf @Pistos Antwort, ab Version 1.9.2 Rubin neue Syntax in den Singletonklasse bekommen
singleton_class = ( class << foo; self; end )
ersetzt werden kann:
singleton_class = foo.singleton_class
Den pragmatischsten / action-oreinted Weg, daran zu denken (IMHO) ist: als Vererbungskette oder Methodennachschlag / Auflösung um. Dieses Bild könnte helfen,
http: // www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
Dies ist r 1,9, kontras builtin und benutzerdefinierten Klassen: i. Diese eine bin immer noch verdauen
http://d.hatena.ne.jp/sumim/20080111/p1
Auch i htink eine verwirrende Verwendung des Begriffs ist „Singleton-Objekt“, die andere Konzept. Ein Singleton-Objekt stammt aus einer Klasse, die den Konstruktor / instantiator Methode hat außer Kraft gesetzt, so dass Sie nur eine dieser Klasse zuordnen können.