respond_to? и защищенные методы - PullRequest
15 голосов
/ 03 апреля 2010

Это может быть не так очевидно, как 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's 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? со вторым аргументом, установленным в true, также проверьте приватный метод

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

И это гораздо разумнее

Итак, вопрос в том, как проверить, отвечает ли объект только на публичный метод? Есть ли решение лучше, чем это?

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

Ответы [ 2 ]

12 голосов
/ 25 июня 2014

Из документации :

Возвращает true, если obj отвечает на данный метод. Частный и Защищенные методы включаются в поиск, только если необязательный второй параметр оценивается как true

Когда вопрос был написан (Ruby 1.8.7):

Возвращает true, если obj отвечает на данный метод. Закрытые методы включаются в поиск только в том случае, если необязательный второй параметр имеет значение true.

8 голосов
/ 03 апреля 2010

Обсуждается, должен ли respond_to? искать защищенные методы или нет (отметьте этот вопрос )

Матц заявил, что он, вероятно, изменится в Ruby 2.0.

Обратите внимание, что некоторые классы могут использовать #method_missing и специализироваться #respond_to? (или лучше указать #respond_to_missing? в Ruby 1.9.2+), в этом случае ваш obj.methods.include? не будет надежным.

...