Shorthand syntax for each, map, reduce & more

Chris Temple
May 25, 2016 · 2 min read

Ruby has a nice shorthand syntax for methods that use blocks and accept Procs, which is very useful when working with enumerables e.g. each, map, reduce etc.

If you’ve been unaware of this syntax, to sum up the numbers in an array you’ve probably been writing code that looks like this:

[1,2,3,4].reduce do |total, number|
total + number
end
=> 10
[1,2,3,4].reduce { |total, number| total + number }
=> 10

The shorthand way of summing up these numbers can be done using the following:

[1,2,3,4].reduce(&:+)
=> 10
[1,2,3,4].reduce(100, &:+)
=> 110

As a personal preference I find this shorthand method much cleaner and easier to read. Another example of how we can use this with our own objects would be:

users.map(&:name)
=> [“Phil Coulson”, “Nick Fury”]
# Assuming a collection of user objects that have a ‘name’ method

How does it work?

The ampersand (&) character does something special when it is used on the last argument of a method call or definition: it will attempt to call the to_proc method on the argument itself.

[1,2,3,4].reduce(&:+)

becomes:

[1,2,3,4].reduce(:+.to_proc)

Symbol#to_proc creates a Proc object that is responsible for calling the :+ method on the object that gets yielded by reduce, for example if we were to write the to_proc method it might look like:

def to_proc
Proc.new { |obj, *args| obj.send(self, *args) }
end

* This example assumes you already know how the Object#send methods works.

Given what we know so far, we can assume the following:

[1,2,3,4].reduce(0, &:+)

becomes:

[1,2,3,4].reduce(0, :+.to_proc)

to_proc would return a Proc similar to:

[1,2,3,4].reduce(0, &(Proc.new { |number, total| number.send(:+, total) }))
=> 10

So each time our reduce methods yields our number, it will:

  1. Call the Proc object the Symbol class created passing (total, number)
  2. Sends the :+ method to be called on number passing total as a parameter.

Recap

# Shorthand way of summing numbers
[1,2,3,4].reduce(&:+)
# Longer/Verbose way
[1,2,3,4].reduce { |number, total| number + total }

Hopefully you find this shorthand syntax as useful and clean as I do.

Let me know what you think.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store