2010-04-02 13 views
15

Może nie być tak oczywiste, jak reagować? działa w ruby. Uważają, że:respond_to? i chronione metody


class A 

    def public_method 
    end 

    protected 
    def protected_method 
    end 

    private 
    def private_method 
    end 

end 

obj = A.new 
obj.respond_to?(:public_method) 
# true - that's pretty obvious 
obj.respond_to?(:private_method) 
# false - as expected 
obj.respond_to?(:protected_method) 
# true - WTF? 

Więc jeśli 'obj' jest odpowiedzią na protected_method powinniśmy oczekiwać

obj.protected_method 

nie zgłaszać wyjątek, nie powinniśmy?

... ale budzi oczywiście

dokumentacja wskazuje, że wywołanie respond_to? Argument z 2-ty ustawiony prawdziwego wyboru metody prywatnym, jak również

obj.respond_to?(:private_method, true) 
# true 

I to o wiele bardziej rozsądne

Więc pytanie brzmi, jak sprawdzić, czy obiekt odpowiada jedynej metody publicznych? Czy istnieje lepsze rozwiązanie?

obj.methods.include?(:public_method) 
# true 
obj.methods.include?(:protected_method) 
# false 

Odpowiedz

8

Jest przedmiotem dyskusji, czy respond_to? należy szukać metod zabezpieczone lub nie (sprawdź this issue)

Matz stwierdził, że będzie to prawdopodobnie zmieni się w Ruby 2.0.

Uwaga niektóre klasy mogą używać #method_missing i specjalizują #respond_to? (lub lepiej określić #respond_to_missing? w Ruby 1.9.2+), w którym to przypadku obj.methods.include? nie będzie wiarygodny.

+0

Ciężko mi zrozumieć przetłumaczony japoński, ale dobrze wiedzieć, że rubinowy rdzeń rozważa tę kwestię. Przynajmniej jeden może użyć obiektu obj.class.public_method_defined? (: Protected_method) i działa zgodnie z oczekiwaniami, ale nie będzie obsługiwał metod singleton, więc uważam, że jako obejście rozwiązanie nie jest prawdziwe – mlomnicki

+0

Odpowiedź zaktualizowana o zaktualizowane informacje –

11

Z documentation:

Zwraca true jeśli obj odpowiada danej metody. Prywatne i chronione metody są wliczone w poszukiwaniu tylko wtedy, gdy opcja drugi parametr wartość true

Gdy pytanie zostało napisane (Ruby 1.8.7):

Zwraca true jeśli obj reaguje na daną metodę. Prywatne metody są uwzględniane w wyszukiwaniu tylko wtedy, gdy opcjonalny drugi parametr ma wartość true.

+1

Pytanie pochodzi z 2010 W Ruby 1.8.7 w dokumentach napisano, że: "Zwraca true", jeśli obiekt obj odpowiada danej metodzie, prywatne metody są uwzględniane w wyszukiwaniu tylko wtedy, gdy opcjonalny drugi parametr jest prawdziwy. " – steenslag

+1

Nadal cenna odpowiedź. Właśnie odkryłem ten ciekawy błąd podczas aktualizacji starego projektu z Ruby '1.8.7' na Ruby' 2.1.1'. –

+0

Jest teraz na stronie [ruby-doc.org] (http://ruby-doc.org/core-2.2.1/Object.html#method-i-respond_to-3F). –

Powiązane problemy