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?
, ordefined?
?
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
Ruby Array to Hash: Each Element the Key and Derive Value from It
How to Stop God from Leaving Stale Resque Worker Processes
How to Disable a Form Submit Button "A Là Ruby on Rails Way"
How to Test If All Items in an Array Are Identical
Is the Unix Philosophy Falling Out of Favor in the Ruby Community
What Grammar Based Parser-Generator Tools Exist for Ruby
Rails: Update Model Attribute Without Invoking Callbacks
Carrierwave Fog Amazon S3 Images Not Displaying
How to Resolve Deprecation Warnings for Openssl::Cipher::Cipher#Encrypt
How to Remove a Non-Breaking Space in Ruby
How to Make a Specific Gem Version as Default
File.Open with Block VS Without
Import SASS Partial Over Http Instead of Filesystem