Why Does Ruby Use Respond_To? Instead of Responds_To

Why does Ruby use respond_to? instead of responds_to?

Matz prefers second person singular or third person plural:

"responds_to?" probably makes more
sense to English speakers than
"respond_to?".

Maybe. But I'm Japanese. Ruby is not
English. It's the basic naming rule
to avoid third person singular form in
the standard libraries.

  you = Human.new
if you.respond_to?(:knock)
...
end

respond_to?' versus 'defined?'

If I want to check whether a method with a given name is defined, which is better to use, respond_to?, or defined??

Neither. Use Module#method_defined?

It's not really a question which is "better" to use: neither the Object#respond_to? method nor the defined? unary prefix operator (despite the name!) checks whether the method is defined: they both check whether the receiver responds to a message, which is a completely different thing.

Only Module#method_defined? will actually check whether the method is defined:

class Foo
def method_missing(*) end
def respond_to_missing?(*) true end
end

foo = Foo.new

defined? foo.bar
#=> 'method'

foo.respond_to?(:bar)
#=> true

Foo.method_defined?(:bar)
#=> false

Confused about respond_to? method

Top-level methods are defined as private, and Object#respond_to? ignores private methods by default (you need to pass second argument for it to recognize say_hello):

def say_hello
puts 'hi'
end

puts respond_to?(:say_hello) #=> false
puts respond_to?(:say_hello, :include_private) #=> true
say_hello

Confused about 'respond_to' vs 'respond_to?'

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.

How does `respond_to` function in rails work?

The methods called on format tell Rails that a response type is available. In the case above, Rails is told that the 2 acceptable response types (in order of preferences) are html and json.

Rails then picks a response type, based on the preference ordering given and the headers of a request. Having made that choice, the block corresponding to the chosen format is called. Until then the blocks passed to the format methods haven't been called - just saved in case that response type is needed.

If a response type has no block, this means that the default action for that response type should be taken. In the case of 'html' this means "find an html template and render it", similar to the implicit render that happens at the end of the action.

All methods in ruby have a return value, but this method's return value is not documented as being anything in particular - don't rely on it.

respond_to? and protected methods

It is under debate if respond_to? should look for protected methods or not (check this issue)

Matz has stated that it will probably change in Ruby 2.0.

Note some classes might use #method_missing and specialize #respond_to? (or better by specify a #respond_to_missing? in Ruby 1.9.2+), in which case your obj.methods.include? will not be reliable.

Responds to method AND is not null check in Ruby?

One line or one method call? unless is simply a logically inverted if so you can put it on one line like this...

if foo.respond_to?(:bar) && !foo.bar.nil?
# do stuff
end

Otherwise you can create a method on foo or some sort of helper that makes the checks in a single call.

Is there a Python equivalent to Ruby's respond_to?

Hmmm .... I'd think that hasattr and callable would be the easiest way to accomplish the same goal:

class Fun:
def hello(self):
print 'Hello'

hasattr(Fun, 'hello') # -> True
callable(Fun.hello) # -> True

You could, of course, call callable(Fun.hello) from within an exception handling suite:

try:
callable(Fun.goodbye)
except AttributeError, e:
return False

As for introspection on the number of required arguments; I think that would be of dubious value to the language (even if it existed in Python) because that would tell you nothing about the required semantics. Given both the ease with which one can define optional/defaulted arguments and variable argument functions and methods in Python it seems that knowing the "required" number of arguments for a function would be of very little value (from a programmatic/introspective perspective).

How do I check if a variable really responds_to :dup?

There isn't really a better way. dup is defined on Object, which means that any class which wants to not respond to it needs to overload it to throw an exception. NilClass, TrueClass, FalseClass, and Number are all subclasses of Object. That means they have to override the method to throw an error.

One way around this, if you are looking for a deep copy anyway, is to use the usual Marshal.load(Marshal.dump(obj)) which will deal with numbers, bools, and nil just fine.

For example:

1.9.3-p392 :001 > obj = "hi"
=> "hi"
1.9.3-p392 :002 > Marshal.load(Marshal.dump(obj)).object_id != obj.object_id
=> true
1.9.3-p392 :003 > obj = 3
=> 3
1.9.3-p392 :004 > Marshal.load(Marshal.dump(obj)).object_id != obj.object_id
=> false


Related Topics



Leave a reply



Submit