When iterating over arrays, there's one piece of shorthand that I find myself using again and again. It's the &: trick, aka the "ampersand colon" or "pretzel colon". In case you're not familiar with it, here's how it works:

words = ["would", "you", "like", "to", "play", "a", "game?"]

# this...
words.map &:length

# ..is equivalent to this:
words.map { |w| w.length }

Until recently, I had assumed that the &: syntax was an operator. But it's not. It's a clever hack that started out in ActiveSupport and became an official feature in Ruby 1.8.7.

The & operator

In addition to being used for AND logic operations, the "&" character has another use in Ruby. When added to the beginning of a method argument, it calls to_proc on its operand and passes it in as a block. That's a mouthful. It's much simpler to see the example:

def my_method(&block)
  block.call
end

class Greeter
  def self.to_proc
    Proc.new { "hello" }
  end
end

my_method(&Greeter) # returns "hello"

Symbol#to_proc

You can add a to_proc method to any object, including Symbol. That's exactly what ruby does to allow for the &: shortcut. It looks something like this:

class Symbol
  def to_proc
    Proc.new do |item|
      item.send self
    end
  end
end

Clear as mud? The important part is item.send(self). Self, in this case refers to the symbol.

Putting it all together

Enumberable methods like each and map accept a block. For each item they call the block and pass it a reference to the item. The block in this case is generated by calling to_proc on the symbol.

# &:name evaluates to a Proc, which does item.send(:name)
items.map(&:name)

The interesting thing about this is that map  doesn't  know any of this is going on!  The bulk of the work is being done by the :name symbol. It's definitely clever...almost too clever for my taste. But it's been a part of Ruby's standard library for years at this point, and it's so handy I doubt I'll stop using it for now. :)

Get the Honeybadger newsletter

Each month we share news, best practices, and stories from the DevOps & monitoring community—exclusively for developers like you.
    author photo
    Starr Horne

    Starr Horne is a Rubyist and former Chief JavaScripter at Honeybadger. When she's not fixing bugs, she enjoys making furniture with traditional hand-tools, reading history and brewing beer in her garage in Seattle.

    More articles by Starr Horne
    An advertisement for Honeybadger that reads 'Move fast and fix things.'

    "We love Honeybadger. Not only is it a fab tool and very affordable, they feel like a partner - whenever we needed help we got FIRST CLASS service."

    Fix errors, eliminate performance bottlenecks, and dig into the details faster than ever before. With support for Ruby, Elixir, and 8 other languages, Honeybadger is the best way to gain real-time insights into your application’s health and performance.

    Get started for free
    Simple 5-minute setup — No credit card required