Confused about 'respond_to' vs 'respond_to?'

Ruby on-Railsrailstutorial.org

Ruby on-Rails Problem Overview


I am learning Rails with railstutorial.org, and I am confused about something: in this chapter the author tells us to do some testing in the console with the respond_to? method on a User object, and it works ok. But later, when we write the test for the :encrypted_password attribute, he uses respond_to.

Out of curiosity, I tried respond_to in the console, for a User object, and I get an error saying the method doesnt exist. Alas, if I try to write the test using respond_to? instead of respond_to, the test doesnt run.

Could someone explain me the difference, and why does the test only run with respond_to?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Ruby treats ? and ! as actual characters in a method name. respond_to and respond_to? are different. ? indicates that this should respond with a true or false (by convention; this is not a requirement). Specifically:

respond_to? is a Ruby method for detecting whether the class has a particular method on it. For example,

@user.respond_to?('eat_food')

would return true if the User class has an eat_food method on it.

respond_to is a Rails method for responding to particular request types. For example:

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

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

However, in the RailsTutorial link you've provided, you're seeing an RSpec method should interacting with RSpec's respond_to method. This wouldn't be available in your console, unless you run rails console test.

Solution 2 - Ruby on-Rails

respond_to? is a Boolean evaluation. The respond_to is used (normally) for determining the display information. More information here. The respond_to? checks to see if a method exists and returns true if it does and false if it doesn't.

Solution 3 - Ruby on-Rails

The test uses convenient helpers to be more user friendly.

Ruby is Ruby so using the good old respond_to? would work if you call it this way:

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

There is another respond_to used in controllers but still nothing to do with those you already met.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionagente_secretoView Question on Stackoverflow
Solution 1 - Ruby on-RailsTim SullivanView Answer on Stackoverflow
Solution 2 - Ruby on-RailsMicharch54View Answer on Stackoverflow
Solution 3 - Ruby on-RailsapneadivingView Answer on Stackoverflow