Difference between {} and do/end

I’m coming back to Ruby after a couple years away, and finding I’ve
forgotten some of the basics. What’s the difference between { … }
blocks and do … end blocks? In particular, why does one of the
following work, while the other fails?

‘%61lice’.gsub! /%(\d+)/ do $1.to_i(16).chr end # => “alice”
‘%61lice’.gsub! /%(\d+)/ { $1.to_i(16).chr } # => SyntaxError

On Feb 20, 11:25 am, Jeff S. [email protected] wrote:

I’m coming back to Ruby after a couple years away, and finding I’ve
forgotten some of the basics. What’s the difference between { … }
blocks and do … end blocks? In particular, why does one of the
following work, while the other fails?

‘%61lice’.gsub! /%(\d+)/ do $1.to_i(16).chr end # => “alice”
‘%61lice’.gsub! /%(\d+)/ { $1.to_i(16).chr } # => SyntaxError

It has to do with operator precedence. {…} has high precedence,
while do … end has low precedence. So in your examples above, the
do…end block is pased to the gsub! method, while the {…} block is
passed to the regex. You can fix the second example using parens:

‘%61lice’.gsub!(/%(\d+)/) { $1.to_i(16).chr } => “alice”

karlvonl wrote:

while do … end has low precedence. So in your examples above, the
do…end block is pased to the gsub! method, while the {…} block is
passed to the regex. You can fix the second example using parens:

‘%61lice’.gsub!(/%(\d+)/) { $1.to_i(16).chr } => “alice”

Thank you!

Jeff S. wrote:

I’m coming back to Ruby after a couple years away, and finding I’ve
forgotten some of the basics. What’s the difference between { … }
blocks and do … end blocks?

Another difference is that {} can be confused with a hash literal. I
can’t think of a good example where it’s actually ambiguous, though.

David M. wrote:

Jeff S. wrote:

I’m coming back to Ruby after a couple years away, and finding I’ve
forgotten some of the basics. What’s the difference between { … }
blocks and do … end blocks?

Another difference is that {} can be confused with a hash literal. I
can’t think of a good example where it’s actually ambiguous, though.

Isn’t

p {1=>2}

such an example? The parser decides that it’s a block and barfs on the
=>.