Confused about 'respond_to' vs 'respond_to?'

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?

83309 次浏览

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.

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.

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.