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?

War es hilfreich?

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

https://apidock.com/ruby/Object/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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top