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?

¿Fue útil?

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top