2009-12-31 13 views
8

Sto provando a verificare se un metodo è definito in un modulo utilizzando Module.method_defined?(:method) e restituisce false deve essere impostato su true.Perché Module.method_defined? (: Method) non funziona correttamente?

module Something 
    def self.another 
    1 
    end 
end 

Something.methods ha 'un altro' elencate, ma Something.method_defined?(:another) rendimenti false.

Forse non funziona perché il metodo è definito su sé? In questo caso, esiste un altro modo per verificare se il metodo è definito sul modulo diverso dall'uso di method_defined??

risposta

10

Per sapere se il modulo ha un metodo di modulo, è possibile utilizzare respond_to? sul modulo :

Something.respond_to?(another) 
=> true 

method_defined? ti dirà se gli INSTANCES della classe con il modulo incluso rispondono al metodo dato.

+2

Forse sto leggendo questo errore, ma non dovrebbe essere 'Something.respond_to? (: Another)' quindi 'another' è un simbolo. Altrimenti non sarebbe "un altro" un errore indefinito? –

5

I metodi dei moduli sono definiti nella metricaforma . Così si può anche verificare per il metodo di inserimento con:

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

Si può leggere di più su di esso in Understanding Ruby Metaclasses.

+0

Il diagramma su quel sito è a dir poco confuso. Che cosa significa l'istanza "eredita" i metodi dalla classe? sembra una terminologia sbagliata per me. Inoltre cosa significa per la freccia con l'etichetta 'instance_eval' che punta al metaclasse? la valutazione 'instance_eval' non si verifica sul metaclasse, accade sull'istanza - l'unica eccezione è il comportamento di' def' in un 'instance_eval' che invece definisce i metodi sul metaclass. – horseyguy

+0

Grazie! Non sono sicuro del motivo per cui l'altra risposta va a segno. Questo è il modo per farlo davvero. –

Problemi correlati