ruby oop singleton

¿Cuál es exactamente la clase singleton en ruby?



oop (4)

Como acaba de actualizar la respuesta de @Pistos, desde la versión 1.9.2 ruby ​​agrega nueva sintaxis para obtener una clase singleton

singleton_class = ( class << foo; self; end )

puede ser reemplazado por:

singleton_class = foo.singleton_class

https://apidock.com/ruby/Object/singleton_class

Parece como si me estuviera perdiendo el sentido o entendiera mal el significado de la clase Singleton en Ruby. He escuchado y leído sobre esto de muchas maneras, algunas más complicadas que otras, pero me siento más confundido sobre lo que es. ¿Es una clase en sí misma? ¿Es la razón por la cual todos los objetos pertenecen a "clase"? El concepto es confuso , pero creo que tiene algo que ver con por qué puedo definir un método de clase en absoluto (clase foo; def foo.bar ...).

Entonces: ¿Cuál es la clase singleton en Ruby?


La manera más pragmática / más orientada a la acción de pensar en ello (en mi humilde opinión) es: como una cadena de herencia, o una búsqueda de método / orden de resolución. Esta imagen podría ayudar

http://www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/

Esto es r 1.9, clases integradas contrastadas 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 "objeto Singleton", que es un concepto diferente. Un objeto singleton proviene de una clase que tiene su método constructor / instanciador anulado para que pueda asignar solo uno de esa clase.


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 de Singleton. Cuando uno 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 de objeto que se crea automáticamente y se inserta en la jerarquía de herencia.

Se puede llamar a singleton_methods 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 article realmente me ayudó a entender Singleton Classes en Ruby y tiene un buen ejemplo de código.


Primero, una pequeña definición: un método singleton es un método que está definido solo para un solo 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 únicos en la instancia de 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 class << obj sintaxis class << obj . Aquí, vemos que esta clase singleton es donde se definen los métodos 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 de agregar métodos singleton a un objeto sería definirlos con la clase singleton del objeto abierta:

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 únicos de una Class
  • 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.