Reputation: 125
The respond_to?
method takes as argument, a method to be checked, but as a symbol.
Why as symbol? And how does ruby convert the method into a symbol?
Upvotes: 5
Views: 883
Reputation: 198324
There's no magic. Methods are attached to objects by their name, which is a symbol. In fact, Math.sin(2)
is basically a shorthand for Math.send(:sin, 2)
("send message :sin
to Math
object, with parameter 2
"). You can also access methods itself: Math.method(:sin)
will give you the associated Method
object (whose name, Math.method(:sin).name
, is of course :sin
), and Math.methods
will list all implemented methods' names. Math.respond_to?(:sin)
can basically be rewritten as Math.methods.include?(:sin)
(this is simplified, as it ignores respond_to_missing?
, but... close enough for this discussion).
Think of it this way. You go to a friend's house, and their mother answers the door. You ask, "Hello, is Tim here?" You don't need to actually drag your friend to the door and ask "Hello, is this individual here?" The name works just as well. :)
EDIT:
Hmmm that's confusing right now for me. What does named mean exactly? I mean maybe with a little example. I call it with array.each. When does the "name" :each come into play then?
I am not sure how to explain it better. Methods have names, just like people have names. When you say array.each
, it is sending the message :each
to the object that is contained in the variable array
, pretty much exactly what array.send(:each)
would do. Methods are pieces of code attached to objects via their names: when an object receives a message, it runs the piece of code that is associated with that message.
Specifically, in the standard Ruby implementation, objects of class Array
, when they receive the message :each
, will invoke the C function rb_ary_each
that is defined in the Ruby source code, and linked to the message :each
using rb_define_method(rb_cArray, "each", rb_ary_each, 0)
(also in the Ruby source code).
Inside Ruby, there are basically two equivalent ways to define methods. These two are equivalent:
class Foo
def bar
puts "hello"
end
end
class Foo
define_method(:bar) do
puts "hello"
end
end
Both of them do the same thing: associate the message :bar
with the piece of code do puts "hello" end
. When :bar
is received by a Foo
(whether through Foo.send(:bar)
or by Foo.bar
), this piece of code is run.
Upvotes: 7