&method shortcut in ruby

Ruby Shortcut to Call a Method with Each Array Item as Parameter

2 min read

As a Ruby programmer, you probably know the &: shortcut to call a method on each item in an array. For example, this snippet will call the to_s method on :foo and :bar.

[:foo, :bar].each(&:to_s)

The above code is similar to:

[:foo, :bar].each do |item|
  item.to_s
end

However, instead of calling a method on the array item, you want to call a method and pass the array item to that method. Is there a one-liner for that?

[:foo, :bar].each do |item|
  puts(item)
end

It turns out, Ruby has a corresponding &method shortcut to accomplish precisely this.

Two things are going on here.

First, the method(:puts) finds the method named puts. As per the documentation, you can access the instance variables and self method on whichever object you called method on.

method(sym) -> method

Looks up the named method as a receiver in obj, returning a Method object (or raising NameError). The Method object acts as a closure in obj’s object instance, so instance variables and the value of self remain available.

Second, the Method object returned by the method method (wow, that’s one too many methods) implements the to_proc method, so you can use it after &, which is to say:

If foo is an object with a to_proc method, then you can pass it to a method as &foo, which will call foo.to_proc and use that as the method’s block.
&method(:puts) # is equivalent to
{ |e| puts(e) }

&:name # is equivalent to
{ |e| e.name }

When you say &method(:puts), it finds the Method object and calls .to_proc on it.

array.each(&method(:foo))

is equivalent to,

array.each { |e| foo(e) }

Is It Worth It?

Now, does that mean you go ahead and replace the explicit method calls in each loops with this one-liner? Probably not.

Sometimes, that explicit method call is just what you need to keep the code readable and easier to understand. Not just for your colleagues, but for the future you. Using this one-liner adds an extra mental overhead for your brain to translate and understand what it’s doing, which is not worth in many cases.

However, sometimes this shortcut is precisely what you need to express what you meant. That’s why I love Ruby. The freedom to choose, do, and say whatever you want, however you want, to write software, well.

Anyway, hope that helps.