ruby metaclass eigenclass singleton

clase<< auto modismo en Ruby



metaclass eigenclass (6)

Que clase << cosa hace:

class Hi self #=> Hi class << self #same as ''class << Hi'' self #=> #<Class:Hi> self == Hi.singleton_class #=> true end end

[hace self == thing.singleton_class en el contexto de su bloque] .

¿Qué es thing.singleton_class?

hi = String.new def hi.a end hi.class.instance_methods.include? :a #=> false hi.singleton_class.instance_methods.include? :a #=> true

hi objeto hereda sus #singleton_class.instance_methods #methods desde su #singleton_class.instance_methods y luego desde su #class.instance_methods .
Aquí dimos el método de instancia de clase singleton de hi :a . Se podría haber hecho con clase << hola en su lugar.
hi ''s #singleton_class tiene todos los métodos de instancia hi '' s #class tiene, y posiblemente algunos más ( :a aquí).

[los métodos de instancia de thing #class y #singleton_class pueden aplicarse directamente a thing. cuando ruby ​​ve thing.a, primero busca: una definición de método en thing.singleton_class.instance_methods y luego en thing.class.instance_methods]

Por cierto, ellos llaman a la clase singleton del objeto == metaclass == eigenclass .

¿Qué hace la class << self mismo en Ruby?


De hecho, si escribe alguna extensión en C para sus proyectos de Ruby, en realidad solo hay una forma de definir un método de Módulo.

rb_define_singleton_method

Sé que este negocio solo abre todo tipo de otras preguntas para que pueda hacerlo mejor buscando cada parte.

Objetos primero.

foo = Object.new

¿Puedo hacer un método para foo?

Por supuesto

def foo.hello ''hello'' end

¿Que hago con esto?

foo.hello ==>"hello"

Solo otro objeto.

foo.methods

Obtienes todos los métodos de objetos más tu nuevo.

def foo.self self end foo.self

Sólo el objeto foo.

Intenta ver qué sucede si haces foo con otros Objetos como Clase y Módulo. Es bueno jugar con los ejemplos de todas las respuestas, pero tienes que trabajar con diferentes ideas o conceptos para entender realmente lo que está sucediendo con la forma en que se escribe el código. Así que ahora tienes muchos términos que ver.

Singleton, Class, Module, self, Object y Eigenclass se mencionaron, pero Ruby no nombra los Modelos de Objetos de esa manera. Es más como metaclase. Richard o __why te muestra la idea aquí. viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html Y, si se queda atrás, intente buscar el Modelo de objetos Ruby en la búsqueda. Dos videos que conozco en YouTube son Dave Thomas y Peter Cooper. Intentan explicar ese concepto también. A Dave le llevó mucho tiempo conseguirlo, así que no te preocupes. Todavía estoy trabajando en eso también. ¿Por qué otra cosa estaría aquí? Gracias por tu pregunta. También eche un vistazo a la biblioteca estándar. Tiene un Módulo Singleton solo como un FYI.

Esto es bastante bueno. https://www.youtube.com/watch?v=i4uiyWA8eFk


Encontré una explicación super simple sobre la class << self , Eigenclass y diferentes tipos de methods en este integralist.co.uk/posts/eigenclass.html .

En Ruby, hay tres tipos de métodos que pueden aplicarse a una clase:

  1. Metodos de instancia
  2. Métodos singleton
  3. Métodos de clase

Los métodos de instancia y los métodos de clase son casi similares a sus homónimos en otros lenguajes de programación.

class Foo def an_instance_method puts "I am an instance method" end def self.a_class_method puts "I am a class method" end end foo = Foo.new def foo.a_singleton_method puts "I am a singletone method" end

Otra forma de acceder a un Eigenclass (que incluye métodos singleton) es con la siguiente sintaxis ( class << ):

foo = Foo.new class << foo def a_singleton_method puts "I am a singleton method" end end

ahora puede definir un método singleton para self que es la clase Foo en este contexto:

class Foo class << self def a_singleton_and_class_method puts "I am a singleton method for self and a class method for Foo" end end end


Primero, la class << foo syntax abre la clase singleton de foo (eigenclass). Esto le permite especializar el comportamiento de los métodos llamados en ese objeto específico.

a = ''foo'' class << a def inspect ''"bar"'' end end a.inspect # => "bar" a = ''foo'' # new object, new singleton class a.inspect # => "foo"

Ahora, para responder a la pregunta: class << self abre self clase singleton de self , de modo que los métodos pueden redefinirse para el objeto self actual (que dentro de una clase o módulo es la clase o el módulo en ). Generalmente, esto se usa para definir los métodos de clase / módulo ("estático"):

class String class << self def value_of obj obj.to_s end end end String.value_of 42 # => "42"

Esto también se puede escribir como una taquigrafía:

class String def self.value_of obj obj.to_s end end

O incluso más corto:

def String.value_of obj obj.to_s end

Cuando se encuentra dentro de una definición de función, self refiere al objeto con el que se llama a la función. En este caso, la class << self abre la clase singleton para ese objeto; Un uso de eso es implementar la máquina de estado de un hombre pobre:

class StateMachineExample def process obj process_hook obj end private def process_state_1 obj # ... class << self alias process_hook process_state_2 end end def process_state_2 obj # ... class << self alias process_hook process_state_1 end end # Set up initial state alias process_hook process_state_1 end

Entonces, en el ejemplo anterior, cada instancia de StateMachineExample tiene process_hook alias para process_state_1 , pero observe cómo en este último, puede redefinir process_hook (solo para el StateMachineExample , sin afectar a otras instancias de StateMachineExample ) a process_state_2 . Por lo tanto, cada vez que una persona que llama llama al método de process (que llama a process_hook redefinible), el comportamiento cambia según el estado en que se encuentre.


Un método singleton es un método que se define solo para un solo objeto.

Ejemplo:

class SomeClass class << self def test end end end test_obj = SomeClass.new def test_obj.test_2 end class << test_obj def test_3 end end puts "Singleton''s methods of SomeClass" puts SomeClass.singleton_methods puts ''------------------------------------------'' puts "Singleton''s methods of test_obj" puts test_obj.singleton_methods

Los métodos de Singleton de SomeClass

prueba

Métodos singleton de test_obj

prueba_2

prueba_3


Usualmente, los métodos de instancia son métodos globales. Eso significa que están disponibles en todas las instancias de la clase en la que se definieron. En contraste, un método singleton se implementa en un solo objeto.

Ruby almacena los métodos en clases y todos los métodos deben estar asociados con una clase. El objeto en el que se define un método singleton no es una clase (es una instancia de una clase). Si solo las clases pueden almacenar métodos, ¿cómo puede un objeto almacenar un método singleton? Cuando se crea un método singleton, Ruby crea automáticamente una clase anónima para almacenar ese método. Estas clases anónimas se llaman metaclases, también conocidas como clases singleton o eigenclasses. El método singleton está asociado con la metaclase que, a su vez, está asociado con el objeto en el que se definió el método singleton.

Si se definen múltiples métodos singleton dentro de un solo objeto, todos se almacenan en la misma metaclase.

class Zen end z1 = Zen.new z2 = Zen.new class << z1 def say_hello puts "Hello!" end end z1.say_hello # Output: Hello! z2.say_hello # Output: NoMethodError: undefined method `say_hello''…

En el ejemplo anterior, la clase << z1 cambia el self actual para apuntar a la metaclase del objeto z1; entonces, define el método say_hello dentro de la metaclase.

Las clases también son objetos (instancias de la clase incorporada llamada Clase). Los métodos de clase no son más que métodos singleton asociados con un objeto de clase.

class Zabuton class << self def stuff puts "Stuffing zabuton…" end end end

Todos los objetos pueden tener metaclases. Eso significa que las clases también pueden tener metaclases. En el ejemplo anterior, la clase << self se modifica a sí mismo para que apunte a la metaclase de la clase Zabuton. Cuando se define un método sin un receptor explícito (la clase / objeto en el que se definirá el método), se define implícitamente dentro del alcance actual, es decir, el valor actual de self. Por lo tanto, el método de relleno se define dentro de la metaclase de la clase Zabuton. El ejemplo anterior es solo otra forma de definir un método de clase. En mi humilde opinión, es mejor usar la sintaxis def self.my_new_clas_method para definir métodos de clase, ya que hace que el código sea más fácil de entender. El ejemplo anterior se incluyó para que entendamos lo que está sucediendo cuando nos encontramos con la sintaxis propia de la clase <<

Se puede encontrar información adicional en este post sobre Ruby Classes .