Stumbling Across Pretzel Colon (&:)

Andrew Edmondson
Sep 6, 2018 · 2 min read

Today, while working under a time crunch (for the last time in my programming career I am sure) I confess to copy-pasting verbatim a solution found on a similar Stack Overflow question without really understanding it. Shame, shame.

The problem was a relatively simple one — I needed to return the longest string element in an array of strings. Imagine:

[“I”, “am”, “looking”, “for this very long string”]

A quick auto-completed google search for “longest string in array ruby” points to this question:
https://stackoverflow.com/questions/22438646/how-can-i-select-the-longest-string-from-a-ruby-array

The highest-voted solution says:

Just do as below using Enumerable#max_by :

ar = [‘one’,’two’,’three’,’four’,’five’]
ar.max_by(&:length) # => “three”

⌘ + c, ⌘ + v and the code passed my test. All done! That is, until I had to explain to another human being what this particular line of code was doing. I had no idea!

This line of code is concise because of a Ruby idiom known as “ampersand colon” or, more endearingly, “pretzel colon.” The pretzel colon is simply shorthand for calling Symbol#to_procon the method following.

Proc objects are blocks of code that have been bound to a set of local variables
http://ruby-doc.org/core-2.0.0/Proc.html

So, in other words,
ar.max_by(&:length)

is equivalent to writing

ar.max_by { |elem| elem.length }

The &: saves a bit of time and typing to translate our iteration statement into a tidy idiom.

Continuing along, ar.max_by is an enumerable method which will, in this example, return the maximum value within the given array: the string with the greatest .length!


Here’s another example to think about:

Referring to an early example on learn.co say we need to shout an array of strings at our hard-of-hearing grandma.

array = [“i”, “love”, “you”, “grandma!”]

This:

array.map {|element| element.upcase} 
# Returns => [“I”, “LOVE”, “YOU”, “GRANDMA!”]

would be equivalent to writing:

array.map(&:upcase) 
# Returns => [“I”, “LOVE”, “YOU”, “GRANDMA!”]

For further reading, please check out Starr Horne’s blog on how the pretzel colon is implemented by Ruby:
http://blog.honeybadger.io/how-ruby-ampersand-colon-works/

As well as Brian Storti’s illuminating explanation with more examples: https://www.brianstorti.com/understanding-ruby-idiom-map-with-symbol/

Andrew Edmondson

Written by

Full-Stack Web Developer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade