2009-11-08 18 views
6

powiedzmy mam następujące 2 klasy:Wykrywanie że metoda nie została przesłonięta

class A 
    def a_method 
    end 
end 

class B < A 
end 

jest to możliwe do wykrycia od wewnątrz (wystąpienie) klasy B, że metoda a_method jest tylko zdefiniowane w nadklasą, a zatem nie jest przesłonięta w B?

Aktualizacja: rozwiązanie

Chociaż mam zaznaczone odpowiedź Chuck jako „zaakceptowany”, później Paolo Perrota uświadomiły mi, że rozwiązanie może pozornie być prostsze, a to prawdopodobnie będzie działać z wcześniejszymi wersjami Ruby też.

Wykrywanie jeśli „a_method” zostaje zastąpione w B:

B.instance_methods(false).include?("a_method") 

A dla metod klasy używamy singleton_methods podobnie:

B.singleton_methods(false).include?("a_class_method") 

Odpowiedz

7

Jeśli używasz Rubiego 1.8.7 lub nowszego, to jest łatwe z Method#owner/UnboundMethod#owner.

class Module 
    def implements_instance_method(method_name) 
    instance_method(method_name).owner == self 
    rescue NameError 
    false 
    end 
end 
+0

Bardzo fajne, dzięki! Szczególnie szczęśliwy po obejrzeniu wersji Ruby, którą pierwotnie wspomniano, zejście z wersji 1.9 na 1.8.7 (której aktualnie używam). – mxgrn

+0

Tak, byłem trochę nieostry. Na początku myślałem, że działa z 1.8.7, a następnie zobaczyłem, że "właściciel metody nr" nie był w dokumentach 1.8.7 ri, więc zmieniłem go na 1.9, a następnie faktycznie sprawdziłem, czy metoda istnieje w wersji 1.8.7 i zobaczyła że miałem to prawo za pierwszym razem. Cieszę się, że to pomaga. – Chuck

0

zawsze można na następujące kwestie i sprawdzić, czy jego definicją tam:

a = A.new 

a.methods.include?(:method) 
+0

PO pyta, jak wykrywać * od wewnątrz klasy B * jeśli to przesłania metodę czy nie. Wiedząc, że klasa A definiuje metodę, nie mówi, czy klasa B nadpisuje ją, czy też nie. –

+0

To jest w porządku, ale jak dodatkowo wykryć, że metoda jest * nie * (oryginalnie) zawarta w metodach instancji B? – mxgrn

+0

well in b nadal możesz zobaczyć, czy A odpowiada na metodę, jeśli tak, a B definiuje tę samą metodę, to oczywiście przesłonił implementację A – ennuikiller

0

Podany obiekt b, który jest instancją B, można przetestować, aby sprawdzić, czy natychmiastowe nadklasą b „s ma a_method:

b.class.superclass.instance_methods.include? 'a_method' 

Zauważ, że test jest przed nazwą metody, a nie symbol lub obiektu metody.

„więc nie są zastępowane w B” - Tylko wiedząc, że metoda jest zdefiniowana tylko w A jest trudne, ponieważ można zdefiniować metody do indywidualnych przypadków A i B ... więc myślę, że to będzie być trudnym do sprawdzenia, że ​​metoda a_method jest zdefiniowana tylko na A, ponieważ musiałbyś zaokrąglić wszystkie podklasy i subwody w systemie i przetestować je ...

2
class A 
    def m1; end 
    def m2; end 
end 

class B < A 
    def m1; end 
    def m3; end 
end 

obj = B.new 
methods_in_class = obj.class.instance_methods(false) # => ["m1", "m3"] 
methods_in_superclass = obj.class.superclass.instance_methods(false) # => ["m2", "m1"] 
methods_in_superclass - methods_in_class # => ["m2"] 
Powiązane problemy