Pages

Thursday, February 10, 2011

The State of Ruby's send Method



Calling a method in Ruby can be thought of as sending a message to an object. This isn't just an abstract concept, it's actually implemented in the language by the send method.

'foo'.length
# => 3
'foo'.send :length
# => 3
This is a really important method in Ruby (often used in meta-programming), so important in fact, that just in case you accidentally overwrite send in your own code, it is aliased as __send__ to make sure it can always be called.

One aspect of send that often causes discussion1 is the fact that it allows you to call private methods which would otherwise be inaccessible using the regular method calling syntax, for example:

class Foo
private
def bar
'baz'
end
end

foo = Foo.new

foo.bar
# => NoMethodError: private method `bar' called for #

foo.send :bar
# => "baz"
And for a while, Ruby 1.9 changed the implementation of send to only allow public methods to be called, introducing a new send! method2 which continued to allow private methods to be called. However, this has now been removed from Ruby 1.9 in favour of keeping the functionality of send as is. Instead, a new public_send method has been introduced which as you might expect will only call public methods.

There are probably others threads, but the send bang method was discussed on the Ruby Talk mailing list.
For forward compatability with Ruby 1.9 send was aliased as send! in Rails as well, although this has also since been removed.