Confused about 'reply_to' vs 'reply_to?'

Я изучаю Rails с railstutorial.org, и я чем-то смущен: в в этой главе автор рассказывает нам провести некоторое тестирование в консоли с помощью метода respond_to? объекта User, и он работает нормально. Но позже, когда мы пишем тест для атрибута :encrypted_password, он использует respond_to.

Из любопытства я попробовал respond_to в консоли, для объекта User, и я получаю сообщение об ошибке, что метод не существует. Увы, если я попытаюсь написать тест, используя respond_to? вместо respond_to, тест не запускается.

Может ли кто-нибудь объяснить мне разницу, и почему тест работает только с respond_to?

Ответ 1

Ruby рассматривает ? и ! как действительные символы в имени метода. respond_to и respond_to? различны. ? указывает, что это должно отвечать истинным или ложным (по соглашению, это не является обязательным требованием). В частности:

respond_to? - это Ruby метод для определения того, имеет ли класс определенный метод на нем. Например,

@user.respond_to?('eat_food')

вернет значение true, если класс User имеет на нем метод eat_food.

respond_to - метод Rails для ответа на конкретные типы запросов. Например:

def index
  @people = Person.find(:all)

  respond_to do |format|
    format.html
    format.xml { render :xml => @people.to_xml }
  end
end

Однако в приведенной ниже ссылке RailsTutorial вы видите метод RSpec should, взаимодействующий с RSpec respond_to метод. Это не будет доступно на консоли, если вы не запустите rails console test.

Ответ 2

respond_to? является булевой оценкой. respond_to используется (обычно) для определения отображаемой информации. Дополнительная информация здесь. respond_to? проверяет, существует ли метод и возвращает true, если это так, и false, если это не так.

Ответ 3

Тест использует удобные помощники, чтобы быть более удобным.

Ruby - Ruby, поэтому использование старого старого respond_to? будет работать, если вы его назовете следующим образом:

 @user.respond_to?(:encrypted_password).should be_true

В контроллерах используется еще один respond_to, но все еще не имеет отношения к тем, с которыми вы уже встречались.