¿Qué hace class << self
en Ruby ?
ruby
metaclass
eigenclass
singleton
randombits
fuente
fuente
Respuestas:
Primero, la
class << foo
sintaxis abrefoo
la clase singleton (clase propia). Esto le permite especializar el comportamiento de los métodos invocados en ese objeto específico.Ahora, para responder a la pregunta:
class << self
abreself
la clase singleton de modo que los métodos se puedan redefinir para elself
objeto actual (que dentro de una clase o cuerpo del módulo es la clase o el módulo en sí ). Por lo general, esto se utiliza para definir métodos de clase / módulo ("estático"):Esto también se puede escribir como una taquigrafía:
O incluso más corto:
Cuando está dentro de una definición de función, se
self
refiere al objeto con el que se llama a la función. En este caso,class << self
abre la clase singleton para ese objeto; un uso de eso es implementar la máquina de estado de un hombre pobre:Entonces, en el ejemplo anterior, cada instancia de se
StateMachineExample
haprocess_hook
aliasadoprocess_state_1
, pero tenga en cuenta cómo en la última, puede redefinirprocess_hook
(self
solo, sin afectar otrasStateMachineExample
instancias) aprocess_state_2
. Por lo tanto, cada vez que una persona que llama llama alprocess
método (que llama redefinibleprocess_hook
), el comportamiento cambia según el estado en el que se encuentre.fuente
class << self
, para crear métodos de clase / módulo. Probablemente ampliaré ese usoclass << self
, ya que es un uso mucho más idiomático.a
'ssingleton_class
ya quea
la clase (después de cambiarinspect
) es una variante única de laString
clase. Si estuviera cambiando laString
clase singleton , afectaría a todas las demásString
instancias. Lo que es más raro aún es que si más adelante vuelve a abrirString
para redefinirinspect
entoncesa
seguirá siendo recoger a los nuevos cambios.class << self
Significa algo más que el valor deself
se establece igual a la clase singleton dentro del alcance del bloque?He encontrado una explicación simple súper sobre
class << self
,Eigenclass
y diferentes tipos de métodos.En Ruby, hay tres tipos de métodos que se pueden aplicar a una 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.
Otra forma de acceder a un
Eigenclass
(que incluye métodos singleton) es con la siguiente sintaxis (class <<
):ahora puede definir un método singleton para el
self
cual es la claseFoo
misma en este contexto:fuente
foo.singleton_class.instance_methods(false)
para verificar.Por lo general, 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. Por el contrario, se implementa un método singleton en un solo objeto.
Ruby almacena 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 denominan metaclases, también conocidas como clases singleton o clases propias. El método singleton está asociado con la metaclase que, a su vez, está asociada 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.
En el ejemplo anterior, la clase << z1 cambia el self actual para apuntar a la metaclase del objeto z1; luego, 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.
Todos los objetos pueden tener metaclases. Eso significa que las clases también pueden tener metaclases. En el ejemplo anterior, la clase << self modifica self para que apunte a la metaclase de la clase Zabuton. Cuando un método se define 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 uno mismo. 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 comprendamos qué sucede cuando nos encontramos con la clase << sintaxis propia.
Se puede encontrar información adicional en esta publicación sobre Ruby Classes .
fuente
¿Qué clase << cosa hace:
[lo hace
self == thing.singleton_class
en el contexto de su bloque] .¿Qué es thing.singleton_class?
hi
objeto hereda su#methods
de su#singleton_class.instance_methods
y luego de su#class.instance_methods
.Aquí le dimos
hi
el método de instancia de clase singleton:a
. Podría haberse hecho con la clase << hola en su lugar.hi
's#singleton_class
tiene todos los métodos de instanciahi
' s#class
tiene, y posiblemente algunos más (:a
aquí).[métodos de instancia de cosa
#class
y#singleton_class
pueden aplicarse directamente a cosa. 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, llaman a la clase singleton del objeto == metaclass == eigenclass .
fuente
El método singleton es un método que se define solo para un solo objeto.
Ejemplo:
Los métodos de Singleton de SomeClass
prueba
Los métodos de singleton de test_obj
prueba_2
prueba_3
fuente
De hecho, si escribe extensiones C para sus proyectos de Ruby, en realidad solo hay una forma de definir un método de Módulo.
Sé que este negocio propio simplemente abre todo tipo de otras preguntas para que pueda mejorar buscando cada parte.
Objetos primero.
¿Puedo hacer un método para foo?
Por supuesto
¿Que hago con esto?
Solo otro objeto.
Obtiene todos los métodos Object más el nuevo.
Solo el foo Object.
Intenta ver qué sucede si haces foo de otros objetos como Class y Module. Es agradable jugar con los ejemplos de todas las respuestas, pero debe trabajar con diferentes ideas o conceptos para comprender realmente lo que sucede con la forma en que se escribe el código. Así que ahora tienes muchos términos para 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 Metaclass. Richard o __ por qué te muestra la idea aquí. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html Y si te sorprende, intenta 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. Dave tardó mucho en conseguirlo, así que no te preocupes. Todavía estoy trabajando en eso también. ¿Por qué más estaría aquí? Gracias por tu pregunta También eche un vistazo a la biblioteca estándar. Tiene un Módulo Singleton como un FYI.
Esto es bastante bueno https://www.youtube.com/watch?v=i4uiyWA8eFk
fuente