2010-04-02 12 views
15

Potrebbe non essere così ovvio come rispondere_to? lavora in rubino. Si consideri che:respond_to? e metodi protetti


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? 

Quindi, se 'obj' risponde a protected_method dovremmo aspettarci

obj.protected_method 

di non sollevare un'eccezione, non dovremmo?

... ma solleva ovviamente

documentazione sottolinea che chiamare respond_to? con 2 ° argomento impostata su true controllo metodo privato così

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

E questo è molto più ragionevole

Quindi la domanda è come controllare se l'oggetto risponde solo metodo pubblico? C'è una soluzione migliore di quella?

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

risposta

8

E 'in discussione se respond_to? dovrebbe cercare metodi protetti o no (controllare this issue)

Matz ha dichiarato che probabilmente cambierà in Ruby 2.0.

Nota alcune classi potrebbero usare #method_missing e specializzarsi #respond_to? (o meglio specificare un #respond_to_missing? in Ruby 1.9.2+), nel qual caso il vostro obj.methods.include? non sarà affidabile.

+0

È difficile per me capire il giapponese tradotto, ma comunque è bello sapere che il nucleo rubino considera quel problema. Almeno uno può usare obj.class.public_method_defined? (: Protected_method) e funziona come previsto ma non gestirà i metodi singleton, quindi preferisco considerarlo come soluzione alternativa non reale – mlomnicki

+0

Risposta aggiornata con informazioni aggiornate –

11

Dal documentation:

restituisce true se obj risponde al metodo dato. e metodi privati ​​protetti sono inclusi nella ricerca solo se il secondo parametro opzionale restituisce true

Quando la questione è stato scritto (Rubino 1.8.7):

restituisce true se obj risponde al metodo dato. I metodi privati ​​sono inclusi nella ricerca solo se il secondo parametro opzionale è true.

+1

La domanda è del 2010 A quel punto in Ruby 1.8.7 i documenti affermavano che: "Restituisce true> se obj risponde al metodo specificato, i metodi privati ​​sono inclusi nella ricerca solo se il secondo parametro opzionale viene valutato come true." – steenslag

+1

Ancora una risposta preziosa. Ho appena scoperto questo strano bug durante l'aggiornamento di un vecchio progetto da Ruby '1.8.7' a Ruby' 2.1.1'. –

+0

È su [ruby-doc.org] (http://ruby-doc.org/core-2.2.1/Object.html#method-i-respond_to-3F) ora. –

Problemi correlati