on programming Rails for fun and profit...

How &:method Shortcut Works in Ruby

This post shows you how Ruby's `&:method` shortcut works behind the scenes. It's a clever trick that was added first in ActiveSupport and became an official feature in Ruby 1.8.7.

How &:method Shortcut Works in Ruby
How &:method Shortcut Works in Ruby

You probably know about Ruby's &:method shortcut.

Given a method name as a symbol prefixed with an & operator, Ruby calls that method on the argument.

In the example below, Ruby calls length on each item.

items = [ 'hi', 'hello' ]
items.map(&:length) # [2, 5]

(1..3).map(&:to_s)  #=> ["1", "2", "3"]

Let's learn how this works.

Behind the Scenes

When you prefix the & operator to a method argument, it calls to_proc on its operand, and passes the result as a block.

You can override the to_proc method to return a custom block, as the Person class does below.

def bar(&block)
  block.call
end

class Person
  def self.to_proc
    -> { puts 'hello world' }
    # Proc.new { puts 'hello world' }
    # proc { puts 'hello world' }
  end
end

bar(&Person) # "hello world"

Now, let's override the Symbol class to add a to_proc method.

It will return a proc/lambda that calls the symbol (self) on its argument (item), using the send method.

class Symbol
  def to_proc
    ->(item) { item.send self }
  end
end

Remember that all symbols (e.g. :item) are instances of Symbol. So you can call to_proc method on a symbol like :item.to_proc.

Now, when you pass &:some_method to a method that accepts a proc, it calls some_method on the argument.

The two calls below are equivalent.

items = [ 'hi', 'hello' ]

items.map(&:length) # [2, 5]
items.map { |item| item.send :length } # [2, 5]

The good news is, we don't have to monkey-patch Symbol to add this method. Ruby already does this. This shortcut was added in ActiveSupport and became official in Ruby 1.8.7.

Pretty nice, right? Let me know in the comments below what you think.

I hope you liked this article and you learned something new. I sure did. If you have any questions or feedback, please send me an email. I look forward to hearing from you.

If you liked this post and would like to receive future posts directly by email, please subscribe below.

You might also enjoy these articles:

Subscribe to Akshay's Blog

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe