Ruby's Symbol to Proc Shorthand: `&:method_name`

When working with Ruby, you’ll often encounter the use of the shorthand array.map(&:method_name) instead of the more verbose array.map { |element| element.method_name }. This shorthand is not only concise but also elegant. In this blog post, we’ll explore how this trick works and why it’s so useful in Ruby programming.

The Verbose Way

Let’s start with the more verbose form, which you might be familiar with:

1
2
array = [1, 2, 3, 4, 5]
squares = array.map { |number| number.to_s }

Here, we’re using the map method to iterate over the array and apply the block { |number| number.to_s } to each element, returning a new array with the results: ["1", "2", "3", "4", "5"].

The Shorthand Way

Ruby provides a shorthand way to achieve the same result using symbols and the & operator:

1
2
array = [1, 2, 3, 4, 5]
squares = array.map(&:to_s)

This converts each element of the array to a string, resulting in ["1", "2", "3", "4", "5"]. While this example uses to_s, the shorthand can be applied to any method.

How Does This Work?

To understand how array.map(&:method_name) works, let’s break it down:

Symbol to Proc Conversion:

The & operator in Ruby can be used to convert a symbol to a Proc object. The symbol :method_name represents the name of the method you want to call on each element of the array.

Creating a Proc Object:

When you prefix a symbol with &, Ruby internally calls to_proc on the symbol. The to_proc method converts the symbol into a Proc object that, when called, invokes the method named by the symbol on its argument.

1
2
   symbol = :to_s
   proc_object = symbol.to_proc

Using the Proc with map:

The map method can accept a block or a Proc. When you pass &:method_name to map, it converts :method_name to a Proc and then calls this Proc on each element of the array.

1
   array.map(&proc_object)

Practical Examples

Let’s look at a few practical examples to see how this shorthand can be used effectively:

Example 1: Converting Numbers to Strings

1
2
3
numbers = [1, 2, 3, 4, 5]
strings = numbers.map(&:to_s)
# Output: ["1", "2", "3", "4", "5"]

In this example, &:to_s converts each number in the array to a string.

Example 2: Getting Lengths of Strings

1
2
3
words = ["apple", "banana", "cherry"]
lengths = words.map(&:length)
# Output: [5, 6, 6]

Here, &:length gets the length of each word in the array.

Example 3: Capitalizing Strings

1
2
3
words = ["hello", "world"]
capitalized_words = words.map(&:capitalize)
# Output: ["Hello", "World"]

In this case, &:capitalize capitalizes each string in the array.

Benefits of Using &:method_name

  1. Conciseness: The shorthand form is more concise and easier to read, especially for simple method calls.
  2. Elegance: It makes the code look cleaner and more elegant, adhering to Ruby’s philosophy of being a language that emphasizes simplicity and productivity.
  3. Consistency: It avoids the repetition of |element| element.method_name, making the intent of the code more immediately clear.

Conclusion

The array.map(&:method_name) shorthand is a powerful and elegant feature in Ruby that allows you to write more concise and readable code. By understanding how the & operator and the to_proc method work together, you can leverage this shorthand to improve the clarity and efficiency of your Ruby programs. Whether you’re converting elements, accessing attributes, or applying transformations, this trick is a valuable addition to your Ruby programming toolkit.