Respond_to? и защищенные методы
Возможно, это не так очевидно, как response_to? работает в рубине.
Предположим, что:
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 pretty obvious
obj.respond_to?(:private_method)
# false - as expected
obj.respond_to?(:protected_method)
# true - WTF?
Итак, если "obj" отвечает на protected_method, мы должны ожидать
obj.protected_method
не создавать исключение, не так ли?
... но он явно поднимается
Документация указывает, что вызывает response_to? с 2-мя аргументами, установленными в true check private method, а также
obj.respond_to?(:private_method, true)
# true
И это гораздо разумнее
Итак, вопрос в том, как проверить, отвечает ли объект только на общедоступный метод?
Есть ли решение лучше, чем это?
obj.methods.include?(:public_method)
# true
obj.methods.include?(:protected_method)
# false
Ответы
Ответ 1
Обсуждается, следует ли respond_to?
искать защищенные методы или нет (отметьте эту проблему)
Мац заявил, что он, вероятно, изменится в Ruby 2.0.
Обратите внимание, что некоторые классы могут использовать #method_missing
и специализировать #respond_to?
(или лучше указать a #respond_to_missing?
в Ruby 1.9.2+), и в этом случае ваш obj.methods.include?
не будет надежным.
Ответ 2
Из документации:
Возвращает true, если obj отвечает данному методу. Частные и защищенные методы включены в поиск, только если необязательный второй параметр оценивается как true
Когда вопрос был написан (Ruby 1.8.7):
Возвращает true, если obj отвечает данному методу. Частные методы включаются в поиск только в том случае, если дополнительный второй параметр имеет значение true.