2010-04-02 13 views
15

Puede que no sea tan obvio cómo responde_to? trabaja en ruby considerar que:respon_to? y métodos protegidos


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? 

Así que si 'obj' responde a protected_method habrá que esperar

obj.protected_method 

no levantar una excepción, no nosotros?

... pero plantea obviamente

documentación señala que llamar respond_to? con el segundo argumento establece en true método de registro privado, así

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

Y eso es mucho más razonable

Así que la pregunta es cómo comprobar si el objeto responde al método público solamente? ¿Hay alguna solución mejor que eso?

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

Respuesta

8

Es objeto de debate si respond_to? debe buscar métodos protegidos o no (marque this issue)

Matz ha declarado que probablemente cambiará en Ruby 2.0.

Nota algunas clases podrían utilizar #method_missing y especializado #respond_to? (o mejor por especificar un #respond_to_missing? en Ruby 1.9.2+), en cuyo caso su obj.methods.include? no será fiable.

+0

Es difícil para mí entender japonés traducido, pero de todos modos es bueno saber que el núcleo de ruby ​​considera ese problema. Al menos uno puede usar obj.class.public_method_defined? (: Protected_method) y funciona como se esperaba, pero no manejará métodos singleton, por lo que más bien considero que como solución no real solución – mlomnicki

+0

Respuesta actualizada con información actualizada –

11

Desde el documentation:

devuelve verdadero si obj responde al método dado. privadas y métodos protegidos se incluyen en la búsqueda sólo si el segundo parámetro opcional se evalúa como verdadera

Cuando la pregunta fue escrito (Rubí 1.8.7):

devuelve true si obj responde al método dado. Los métodos privados se incluyen en la búsqueda solo si el segundo parámetro opcional se evalúa como verdadero.

+1

La pregunta es de 2010 En aquel entonces, en Ruby 1.8.7, los documentos indicaban que: "Devuelve true> si obj responde al método dado. Los métodos privados se incluyen en la búsqueda solo si el segundo parámetro opcional se evalúa como verdadero". – steenslag

+1

Sigue siendo una respuesta valiosa. Acabo de descubrir este curioso error al actualizar un viejo proyecto de Ruby '1.8.7' a Ruby' 2.1.1'. –

+0

Está en [ruby-doc.org] (http://ruby-doc.org/core-2.2.1/Object.html#method-i-respond_to-3F) ahora. –

Cuestiones relacionadas