Dominik Huber
Dominik Huber

Reputation: 125

How can Ruby transform a method into a symbol as argument?

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

Answers (1)

Amadan
Amadan

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

Related Questions