# Difference between {} and do/end

**URL:** <https://www.ruby-forum.com/t/difference-between-and-do-end/160890>\
**Category:** Ruby\
**Created:** [February 20, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890 "2009-02-20T17:30:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sprsquish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sprsquish](https://www.ruby-forum.com/u/sprsquish)\
**Post date:** [February 20, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890/1 "2009-02-20T17:30:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![sprsquish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sprsquish](https://www.ruby-forum.com/u/sprsquish)\
**Post date:** [February 20, 2009, 5:41pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890/2 "2009-02-20T17:41:33Z")

</div>

On Feb 20, 11:25 am, Jeff S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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”

---

<div class="post-metadata">

**Author:** ![sprsquish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sprsquish](https://www.ruby-forum.com/u/sprsquish)\
**Post date:** [February 20, 2009, 6:29pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890/3 "2009-02-20T18:29:20Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![sprsquish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sprsquish](https://www.ruby-forum.com/u/sprsquish)\
**Post date:** [February 20, 2009, 11:31pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890/4 "2009-02-20T23:31:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sprsquish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sprsquish](https://www.ruby-forum.com/u/sprsquish)\
**Post date:** [February 20, 2009, 11:47pm UTC](https://www.ruby-forum.com/t/difference-between-and-do-end/160890/5 "2009-02-20T23:47:32Z")

</div>

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  
=\>.
