2009-12-31 17 views
8

Estoy tratando de verificar si un método está definido en un módulo que usa Module.method_defined?(:method) y devuelve falso, debe retornar verdadero.¿Por qué Module.method_defined? (: Method) no funciona correctamente?

module Something 
    def self.another 
    1 
    end 
end 

Something.methods tiene 'otro' en la lista pero Something.method_defined?(:another) vuelve false.

¿Esto quizás no funciona porque el método está definido en sí mismo? Si este es el caso, ¿hay otra forma de verificar si el método está definido en el módulo que no sea el method_defined??

Respuesta

10

Para saber si el módulo tiene un método de módulo, puede usar responder_¿? en el módulo :

Something.respond_to?(another) 
=> true 

method_defined? le dirá si INSTANCES de la clase con el módulo incluido responde al método dado.

+2

Quizás estoy leyendo esto mal, pero ¿no debería ser 'Something.respond_to? (: Another)' entonces 'another' es un símbolo. De lo contrario, ¿no causaría 'otro' un error indefinido? –

5

Los métodos de los módulos se definen en su metaclass. Así también se puede comprobar con la inclusión método:

k = class << Something; self; end # Retrieves the metaclass 
k.method_defined?(:another) #=> true 

Usted puede leer más sobre esto en Understanding Ruby Metaclasses.

+0

El diagrama en ese sitio es confuso por decir lo menos. ¿Qué significa la instancia 'heredar' los métodos de la clase? parece una terminología equivocada para mí. Además, ¿qué significa la flecha con la etiqueta 'instancia_eval' que apunta a la metaclase? La evaluación 'instance_eval' no ocurre en la metaclase, ocurre en la instancia, la única excepción es el comportamiento de' def' en 'instance_eval' que en su lugar define los métodos en la metaclase. – horseyguy

+0

¡Gracias! No estoy seguro de por qué la otra respuesta es la marca de verificación. Esta es la manera de hacerlo realmente. –

Cuestiones relacionadas