2010-04-02 8 views
15

Es kann nicht so offensichtlich sein, wie reply_to? arbeitet in Rubin. Bedenken Sie, dass:Antwort? und geschützte Methoden


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? 

Also, wenn 'obj' auf protected_method reagiert sollten wir erwarten,

obj.protected_method 

keine Ausnahme zu erhöhen, sollten wir nicht? offensichtlich

... aber es wirft

Dokumentation zeigt, dass respond_to Aufruf? mit 2. auf true Check private Methode gesetzt Argument auch

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

Und das ist viel vernünftiger

Die Frage ist also, wie Sie überprüfen, wenn das Objekt nur auf öffentliche Methode reagiert? Gibt es eine bessere Lösung?

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

Antwort

8

Es ist umstritten, ob respond_to? für geschützte Methoden aussehen sollte oder nicht (überprüfen this issue)

Matz hat erklärt, dass es wahrscheinlich in Ruby 2.0 ändern wird.

Hinweis einiger Klassen #method_missing verwenden könnten und spezialisieren #respond_to? (oder besser durch ein #respond_to_missing? in Ruby angeben 1.9.2+), wobei in diesem Fall Ihre obj.methods.include? nicht zuverlässig sein.

+0

Es ist schwer für mich zu verstehen, Japanisch übersetzt, aber trotzdem gut zu wissen, dass Rubin-Kern dieses Problem betrachten. Mindestens einer kann obj.class.public_method_defined? (: Protected_method) verwenden, und es funktioniert wie erwartet, aber nicht mit Singleton-Methoden, so dass ich eher als Umgehungslösung keine echte Lösung – mlomnicki

+0

Antwort mit aktualisierten Informationen –

11

Vom documentation:

Gibt true zurück, wenn obj an die angegebene Methode reagiert. Private und geschützten Methoden werden in die Suche einbezogen nur, wenn die optionale zweite Parameter den Wert true

Wenn die Frage geschrieben wurde (Rubin 1.8.7):

Gibt true zurück, wenn obj reagiert auf die gegebene Methode. Private Methoden werden nur dann in die Suche einbezogen, wenn der optionale zweite Parameter true ergibt.

+1

Die Frage ist von 2010 In Ruby 1.8.7 hieß es dann in den Dokumenten: "Gibt true zurück, wenn obj auf die angegebene Methode anspricht. Private Methoden werden nur dann in die Suche einbezogen, wenn der optionale zweite Parameter true ergibt." – steenslag

+1

Noch eine wertvolle Antwort. Ich habe gerade diesen seltsamen Bug entdeckt, als ich ein altes Projekt von Ruby '1.8.7' auf Ruby' 2.1.1' hochrüste. –

+0

Es ist jetzt auf [ruby-doc.org] (http://ruby-doc.org/core-2.1/Object.html#method-i-respard_to-3F). –