How can Ruby convert a method to a symbol as an argument?
There is no magic. Methods are attached to objects by their name, which is a symbol. In fact, it 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 the methods yourself: Math.method(:sin)
will provide you with an associated object Method
(whose name Math.method(:sin).name
, of course, :sin
), and Math.methods
will list all the names of the implemented methods. Math.respond_to?(:sin)
can in principle 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, "Hey is Tim here?" You don't have to actually drag your friend to the door and ask, "Hey, is this human here?" The title works just as well. :)
EDIT:
Hmmm I'm confused now. What is named so accurately? I mean with maybe a little example. I call this an array. When the "name" appears: does each one come into play?
I'm not sure how to explain this better. Methods have names, just as people have names. When you say it array.each
, it sends a message to the :each
object contained in the variable array
, exactly what to do array.send(:each)
. Methods are pieces of code attached to objects through their names: when an object receives a message, it runs the piece of code associated with that message.
In particular, in the standard Ruby implementation, class objects array
, when they receive a message :each
, call a C function rb_ary_each
that is defined in the Ruby source code and associated with the message :each
using rb_define_method(rb_cArray, "each", rb_ary_each, 0)
(also in the Ruby source code).
Within Ruby, there are 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
They both do the same thing: link a message :bar
to a piece of code do puts "hello" end
. When :bar
received Foo
(via Foo.send(:bar)
or Foo.bar
), this piece of code is run.
source to share