Ruby Block Precedence

Ruby has two succinct ways of representing a block:

weekdays = %w[monday tuesday wednesday thursday friday]

# longer form
weekdays.each do |day|
  puts day.capitalize
end

# shorter form
weekdays.each { |d| puts d.capitalize }

# both blocks output:

Monday
Tuesday
Wednesday
Thursday
Friday

However, there is a slight difference as demonstrated next, where we select our training days.

The short form:

puts weekdays.select { |d| d.start_with? "t" }

# outputs:

tuesday
thursday

Versus the long form:

puts weekdays.select do |d|
  d.start_with? "t"
end

# outputs:

#<Enumerator:0x0000556f2afd0090>

Uh oh..what happened to our output, where did our training days go?

The reason this happened is because in the long form the puts binds tighter to the select enumerator. The puts receives this enumerator, and the code block we provided, but ignores the code block and prints the enumerator. To avoid any confusion, we can assign the result of the select to another array, and then print that:

training_days = weekdays.select do |d|
  d.start_with? "t"
end

puts(training_days)

# outputs:

tuesday
thursday

As you can see, there is a slight difference between the two forms of block expression.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s