2010-04-02 2 views
15

Возможно, это не так очевидно, как response_to? работает в рубине. Считают, что:reply_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 

не возбудит исключение, не должны ли мы?

... но это поднимает очевидно

документации указывает, что вызов respond_to? с вторым аргументом установлен истинной проверкой частного метода, а

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

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

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

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

ответ

8

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

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

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

+0

Мне сложно понять, что переведенный японский язык, но в любом случае хорошо знать, что рубиновый стержень рассматривает эту проблему. По крайней мере, один может использовать obj.class.public_method_defined? (: Protected_method), и он работает так, как ожидалось, но не будет обрабатывать однотонные методы, поэтому я скорее считаю это как workaround не реальное решение – mlomnicki

+0

Отвечено обновлено с обновленной информацией –

11

От documentation:

Возвращает истину, если OBJ отвечает данному методу. Частные и защищенные методы включены в поиск, только если дополнительный второй параметр имеет значение истинного

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

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

+1

Вопрос с 2010 года В то время как в Ruby 1.8.7 документы указали, что: «Возвращает true>, если obj отвечает на данный метод. Частные методы включаются в поиск, только если дополнительный второй параметр имеет значение true». – steenslag

+1

Еще ценный ответ. Я только что обнаружил эту любопытную ошибку при обновлении старого проекта с Ruby '1.8.7' до Ruby' 2.1.1'. –

+0

Сейчас он [ruby-doc.org] (http://ruby-doc.org/core-2.2.1/Object.html#method-i-respond_to-3F). –

Смежные вопросы