¿Qué es exactamente la clase singleton en Ruby?
Pregunta
¿Es la clase singleton en Ruby una clase en sí misma?¿Es la razón por la cual todos los objetos pertenecen a "clase"? El concepto es difuso, pero creo que tiene algo que ver con por qué puedo definir un método de clase (class foo; def foo.bar ...
).
¿Cuál es la clase singleton en Ruby?
Solución
Primero, una pequeña definición: un método singleton es un método que se define solo para un único objeto. Ejemplo:
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
Los métodos de instancia son métodos de una clase (es decir, definidos en la definición de la clase). Los métodos de clase son métodos singleton en la instancia Class
de una clase; no están definidos en la definición de la clase. En cambio, se definen en la clase singleton del objeto.
irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false
Abre la clase singleton de un objeto con la sintaxis class << obj
. Aquí, vemos que esta clase de singleton es donde se definen los métodos de 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
Entonces, un medio alternativo para agregar métodos singleton a un objeto sería definirlos con la clase singleton abierta del objeto:
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
En resumen:
- los métodos siempre deben pertenecer a una clase (o: ser métodos de instancia de alguna clase)
- los métodos normales pertenecen a la clase en la que están definidos (es decir, son métodos de instancia de la clase) Los
- métodos de clase son solo métodos singleton de un <=>
- los métodos singleton de un objeto no son métodos de instancia de la clase del objeto; más bien, son métodos de instancia de la clase singleton del objeto.
Otros consejos
Ruby proporciona una forma de definir métodos que son específicos de un objeto en particular y dichos métodos se conocen como métodos Singleton. Cuando se declara un método singleton en un objeto, Ruby crea automáticamente una clase para contener solo los métodos singleton. La clase recién creada se llama 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 clase Singleton es una clase anónima específica del objeto que se crea e inserta automáticamente en la jerarquía de herencia.
singleton_methods
se puede invocar en un objeto para obtener la lista de nombres para todos los métodos singleton en un objeto.
foo.singleton_methods # => [:size]
bar.singleton_methods # => []
Este artículo realmente me ayudó a comprender las clases Singleton en Ruby y tiene un buen código ejemplo.
Como recién actualicé la respuesta de @Pistos, desde la versión 1.9.2 Ruby agrega una nueva sintaxis para obtener la clase singleton
singleton_class = ( class << foo; self; end )
se puede reemplazar con:
singleton_class = foo.singleton_class
La forma más pragmática / orientada a la acción de pensarlo (en mi humilde opinión) es: como una cadena de herencia, u orden de búsqueda / resolución de métodos. Esta imagen puede ayudar
http: // www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
Esto es r 1.9, contrastando clases integradas y definidas por el usuario: todavía estoy digiriendo esta.
http://d.hatena.ne.jp/sumim/20080111/p1
Además, creo que un uso confuso del término es " Singleton object " ;, que es un concepto diferente. Un objeto singleton proviene de una clase que tiene su método de constructor / instanciador anulado para que pueda asignar solo una de esa clase.