In Ruby’s syntax, putting an ampersand ( & ) before the last parameter in a method call causes a to_proc method to be called on it and the result to be used as the block for the method invocation. Originally, this was largely used for storing blocks as Procs inside the method, and then turning them back into blocks when calling another method.

Ruby 1.9 added a to_proc instance method to the Symbol class, known as Symbol#to_proc . The implementation of this method causes the object yielded to the block to have the method named by the symbol to be invoked on it. For example, let’s say that we have an array of floating-point numbers and we want to find the closest integer value for each:

numbers = [ 1.23 , 4.56 , 7.89 ] nearest = numbers.map{ |n| n.round } nearest = numbers.map( & :round )

This allows for code that’s easier to type, easier to read (once you know what you’re looking at), and is generally better.

Today, however, I found out that it is even more powerful. If more than one parameter is passed to your block, the proc created by Symbol#to_proc uses the additional block parameters as parameters to the method call. If you have code that looks like this:

some_method do |foo, bar, baz| foo.swizzle( bar, baz ) end

…then you can rewrite it in Ruby 1.9 as just:

some_method(& :swizzle )

Where do we often see blocks that yield two parameters? Why, in our good friend Enumerable#inject !

values = [ 1 , 2 , 3 , 4 , 5 , 6 ] total = values.inject( 0 ){ |sum, num| sum + num } total = values.inject( 0 ,& :+ )

I have a feeling that this will prove useful beyond impressively terse code. The one damper on this parade, however, is that you must have two values actually being yielded to your block. Yielding an array that has two values is not good enough:

players.zip(turn_scores).each{ |player,turn_score| player.add_score(turn_score) } players.zip(turn_scores).each(& :add_score )

The Solution

All is not lost, however. Since all the Enumerable methods return an Enumerator if you call them without a block, we can monkeypatch that class to yield all values explicitly:

class Enumerator def splatted each{ |a| yield (*a) } end end

With this, we can now do some wonderful things: