2009-12-31 5 views
8

Ich versuche zu überprüfen, ob eine Methode in einem Modul mit Module.method_defined?(:method) definiert ist und es gibt false zurück, es sollte wahr sein.Warum funktioniert Module.method_defined? (: Method) nicht richtig?

module Something 
    def self.another 
    1 
    end 
end 

Something.methods hat 'andere' aufgeführt, aber Something.method_defined?(:another) kehrt false.

Funktioniert das vielleicht nicht, weil die Methode auf self definiert ist? Wenn dies der Fall ist, gibt es eine andere Möglichkeit zu überprüfen, ob die Methode auf dem Modul anders definiert ist als method_defined??

Antwort

10

Um zu wissen, ob das Modul eine Modulmethode hat, können Sie reply_to verwenden? auf dem Modul:

Something.respond_to?(another) 
=> true 

method_defined? wird Ihnen sagen, ob INSTANCES der Klasse mit dem enthaltenen Modul auf die angegebene Methode reagiert.

+2

Vielleicht lese ich das falsch, aber sollte es nicht 'Something.respond_to? (: Ein anderes)' so 'ein anderes' ist ein Symbol. Würde sonst nicht "ein anderer" einen undefinierten Fehler verursachen? –

5

Module Methoden sind in seiner Metaklasse definiert. So können Sie auch für die Methode Aufnahme überprüfen:

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

Sie können mehr über sie in Understanding Ruby Metaclasses lesen.

+0

Das Diagramm auf dieser Seite ist verwirrend, um es gelinde auszudrücken. Was bedeutet es, dass die Instanz die Methoden von der Klasse erbt? scheint mir eine falsche Terminologie zu sein. Was bedeutet es auch, wenn der Pfeil 'instance_eval' auf die Metaklasse verweist? 'instance_eval' findet nicht in der Metaklasse statt, sondern in der Instanz. Die einzige Ausnahme ist das Verhalten von' def' in 'instance_eval', das stattdessen Methoden für die Metaklasse definiert. – horseyguy

+0

Danke! Nicht sicher, warum die andere Antwort das Häkchen setzt. Dies ist der Weg, es tatsächlich zu tun. –

Verwandte Themen