---
title: "The clever hack that makes `items.map(&:name)` work"
published: "2015-07-01"
publisher: Honeybadger
author: Starr Horne
category: Ruby articles
tags:
  - Ruby
description: "The &: trick is a great shortcut when using enumerable methods like map. The way it works may surprise you. In this post we'll look in detail at exactly how code like users.map(&:name) functions under the hood."
url: "https://www.honeybadger.io/blog/how-ruby-ampersand-colon-works/"
---

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:

```ruby
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:

```ruby
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:

```ruby
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.

```ruby
# &: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. :)

---

## Try Honeybadger for FREE

Intelligent logging, error tracking, and Just Enough APM™ in one dev-friendly platform. Find and fix problems before users notice.

[Start free trial](https://app.honeybadger.io/users/sign_up)

[See plans and pricing](https://www.honeybadger.io/plans/)
