2009-12-31 13 views
8

Próbuję sprawdzić, czy metoda jest zdefiniowana w module przy użyciu Module.method_defined?(:method) i zwraca false, powinno być prawdziwe.Dlaczego metoda Module.method_defined? (: Method) nie działa poprawnie?

module Something 
    def self.another 
    1 
    end 
end 

Something.methods ma 'inny' na liście, ale Something.method_defined?(:another) powraca false.

Czy to może nie działać, ponieważ metoda jest zdefiniowana na własny rachunek? Jeśli tak, to czy istnieje inny sposób sprawdzenia, czy metoda jest zdefiniowana w module innym niż przy użyciu method_defined??

Odpowiedz

10

Aby sprawdzić, czy moduł ma metodę modułu, można użyć parametru respond_to? na module :

Something.respond_to?(another) 
=> true 

method_defined? pokaże ci, czy instancje klasy z dołączonym modułem odpowiadają na daną metodę.

+2

Być może czytam to źle, ale nie powinno to być "Something.respond_to? (: Another)' so 'another' jest symbolem. W przeciwnym razie "inny" nie spowodowałby niezdefiniowanego błędu? –

5

Metody modułowe są zdefiniowane w metodzie metaclass. Więc można również sprawdzić na włączenie metody z:

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

Możesz przeczytać więcej na ten temat w Understanding Ruby Metaclasses.

+0

Schemat na tej stronie jest co najmniej mylący. Co to znaczy, że instancja "dziedziczy" metody z klasy? wydaje mi się niewłaściwą terminologią. Co to też znaczy strzałką oznaczoną 'instance_eval' wskazującą na metaklass? Ocena 'instance_eval' nie występuje w metaklassie, dzieje się to na instancji - jedynym wyjątkiem jest zachowanie' def' w 'instance_eval', które zamiast tego definiuje metody w metaklassie. – horseyguy

+0

Dziękujemy! Nie wiem, dlaczego w drugiej odpowiedzi znajduje się znacznik wyboru. To jest sposób, aby to zrobić. –

Powiązane problemy