Considere la siguiente clase:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
Esto no es un problema y puede llamar Foo.new.a_new_inst_method
sin problemas.
Me gustaría tener un método de clase como Foo.add_widget(*items)
y alias para poder hacer algo como:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
Así que, esencialmente, tiene un "estilo rubí" similar 1.minute
y, 2.minutes
por lo tanto, quiero usar un alias Foo.add_widget
para llamar a las Foo.add_widgets
llamadas exactamente el mismo método. Sé que podría envolverlo, pero siento que debería poder hacerlo de una manera más limpia.
Considere mi intento de intentar algo como esto:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
Sin embargo, me sale el siguiente error:
NameError (undefined method `a_class_method' for class `Foo')
Y parece que esto no funciona para los métodos de clase. ¿Cómo voy a hacer esto?
fuente
extend ClassMethods
solución. +1Lo importante a entender es que no existe un método de clase en Ruby.
Un método de clase es realmente solo un método singleton. No hay nada especial sobre los métodos de clase. Cada objeto puede tener métodos singleton. Simplemente los llamamos "métodos de clase" cuando el objeto es
Class
porque "el método singleton de una instancia deClass
" es demasiado largo y difícil de manejar.¡Espere! ¿Dije "método singleton"?
Otra cosa importante a entender es que no existe el método singleton en Ruby.
Un método singleton es realmente un método de instancia antiguo aburrido de la clase singleton. No hay nada especial sobre los métodos singleton. Son solo métodos de instancia como cualquier otro método de instancia.
De hecho, Ruby solo tiene métodos de instancia. Sin funciones, sin constructores, sin métodos estáticos, sin métodos de clase, sin funciones de módulo, sin métodos singleton.
La pregunta no es "¿es este un método de clase, es un método singleton", sino "en qué módulo se define este método?"
Los "métodos Singleton" son realmente métodos de instancia definidos en la clase Singleton. La sintaxis para acceder a la clase singleton de
foo
esTambién hay un método
Object#singleton_class
que devuelve la clase singleton de un objeto.¿Por qué estoy insistiendo tan agresivamente en el hecho de que cada método es un método de instancia y que los métodos de clase no existen? ¡Porque significa que el modelo de objetos de Ruby es mucho más simple de lo que la gente piensa! Después de todo, en su pregunta, ya muestra que sabe cómo alias métodos de instancia, pero dice que no sabe cómo alias métodos de clase. ¡Pero eso está mal! Usted hace saber cómo los métodos de clase alias, ya que son métodos de instancia sólo . Si te hubieran enseñado este hecho correctamente, ¡nunca hubieras necesitado hacer esta pregunta!
Una vez que comprenda que cada método es un método de instancia, y que lo que llamamos "métodos singleton" son solo métodos de instancia de la clase singleton, la solución queda clara:
Nota: cuando escribí anteriormente que "no hay tal cosa como X", lo que quise decir fue que "no hay tal cosa como X en el lenguaje Ruby ". Eso no significa que esos conceptos no existan en la comunidad Ruby .
Hablamos regularmente de "métodos singleton" y "métodos de clase", simplemente porque es más fácil que hablar de "métodos de instancia de la clase singleton" o "métodos de instancia de la clase singleton de un objeto que resulta ser una instancia de la
Class
clase ". Hay incluso métodos comoObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, yModule#module_function
en la biblioteca núcleo Ruby. Pero siempre es importante recordar que esos no son conceptos de lenguaje. Esos son conceptos comunitarios que solo existen en nuestras cabezas y en los nombres de algunos métodos de biblioteca.fuente
OK, parece que puedo hacer algo como esto y funcionará:
Si alguien tiene información útil sobre el lenguaje Ruby aquí y desea enviar una respuesta completa, le daré un +1.
fuente
class << self
enalias_method :a_new_class_method, :a_class_method
realidad recurresalias_method
a la clase singleton deFoo
. Otra forma de escribir esto es:singleton_class.alias_method :a_new_class_method, :a_class_method
en contexto de clase.alias_method
opera en la instancia, por lo que debe ir un nivel más profundo y operar en laClass
instancia, o la metaclase de la clase . Ruby tiene un modelo de objeto salvaje que puede ser una especie de rompe cerebro, pero también te da un montón de poder:fuente