Che cosa è esattamente la classe singleton in ruby?
Domanda
È la classe singleton in Ruby una classe in sé e per sé?È il motivo per cui tutti gli oggetti che appartengono alla "classe?" Il concetto è fuzzy, ma credo che abbia qualcosa a che fare con il motivo per cui sono in grado di definire un metodo di una classe a tutti (class foo; def foo.bar ...
).
Qual è la classe singleton in Ruby?
Soluzione
Innanzitutto, una piccola definizione: un metodo singleton è un metodo definito solo per un singolo oggetto. Esempio:
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
I metodi di istanza sono metodi di una classe (cioè definiti nella definizione della classe). I metodi di classe sono metodi singleton nell'istanza Class
di una classe - non sono definiti nella definizione della classe. Invece, sono definiti nella classe singleton dell'oggetto.
irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false
Si apre la classe singleton di un oggetto con la sintassi class << obj
. Qui, vediamo che questa classe singleton è dove sono definiti i metodi singleton:
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
Quindi un mezzo alternativo per aggiungere metodi singleton a un oggetto sarebbe definirli con la classe singleton dell'oggetto aperta:
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
In sintesi:
-
I metodi
- devono sempre appartenere a una classe (o: essere metodi di istanza di una classe)
- i metodi normali appartengono alla classe in cui sono definiti (ovvero sono metodi di istanza della classe) I metodi di classe
- sono solo metodi singleton di un <=>
- i metodi singleton di un oggetto non sono metodi di istanza della classe dell'oggetto; piuttosto, sono metodi di istanza della classe singleton dell'oggetto.
Altri suggerimenti
Ruby fornisce un modo per definire metodi specifici per un particolare oggetto e tali metodi sono noti come Metodi Singleton. Quando si dichiara un metodo singleton su un oggetto, Ruby crea automaticamente una classe per contenere solo i metodi singleton. La classe appena creata si chiama Singleton Class.
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
La classe Singleton è una classe anonima specifica dell'oggetto che viene automaticamente creata e inserita nella gerarchia dell'ereditarietà.
singleton_methods
può essere chiamato su un oggetto per ottenere l'elenco di nomi per tutti i metodi singleton su un oggetto.
foo.singleton_methods # => [:size]
bar.singleton_methods # => []
Questo articolo mi ha davvero aiutato a capire le lezioni di Singleton in Ruby e ha un buon codice esempio.
Come aggiornare a @Pistos risposta, dalla versione 1.9.2 ruby aggiungere una nuova sintassi per ottenere classe singleton
singleton_class = ( class << foo; self; end )
può essere sostituito con:
singleton_class = foo.singleton_class
Il modo più pragmatico / orientato all'azione di pensarlo (IMHO) è: come una catena di eredità, o ordine di ricerca / ordine del metodo. Questa immagine potrebbe essere utile
http: // www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
Questa è la r 1.9, che contrappone le classi predefinite e definite dall'utente: sto ancora digerendo questa.
http://d.hatena.ne.jp/sumim/20080111/p1
Inoltre, penso che un uso confuso del termine sia " Singleton object " ;, che è un concetto diverso. Un oggetto singleton proviene da una classe che ha il suo metodo di costruzione / istanza sovrascritto in modo da poter allocare solo una di quella classe.