Ruby blocks: Braces and do/end have different precedence

Braces and do/end are completely swappable—almost all the time. They have different precedence. It’s not often that anyone comes across what this means in practice.

TL;DR {} binds stronger than do…end (as always in Ruby, special characters bind stronger than words)

Demo

Right way

names = ['bRUce', 'STaN', 'JOlIE']

# Blocks in braces are passed to the rightmost method
print names.map { |name| name.downcase }
print(names.map do |name| name.downcase end) # equivalent
=> ["bruce", "stan", "jolie"]

Wrong way

Avoid the examples below, as you pass at least one block to print and not to the enumerator.

names = ['bRUce', 'STaN', 'JOlIE'] 

# Blocks in do…end are passed to the leftmost method
print names.map do |name| name.downcase end
print(names.map) { |name| name.downcase } # equivalent
=> #<Enumerator:0x00000001e793b0>

# Combined
print names.map { |name| name.downcase } do |name| name.capitalize end
print(names.map { |name| name.downcase }) do |name| name.capitalize end # equivalent
=> ["bruce", "stan", "jolie"]
Henning Koch over 9 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more