You may also write a one liner of the do block although it's really only useful when doing something like eval("my_array.each do |item|;puts item;end") but it works in irb or pry without eval and quote marks You may come across a situation when that is preferred. Don't ask me when though. That's another topic to be investigated.
– Douglas G. AllenFeb 18 '15 at 16:03

Ah, got it. So because of the precedence order, when you use do, you're passing the block as an additional parameter, but when you use the brackets you're passing the block as the first parameter of the results of the method invocation(s) to the left.
– Alan StormJan 23 '10 at 18:09

Basically, it comes down to, if your block logic goes to multiple lines and cannot be fitted on the same line then use do .. end and if your block logic is simple and just a simple/single line of code then use {}.

I agree with using do/end for multi-line blocks, but I will go with braces if I'm chaining additional methods to the end of the block. Stylistically I like {...}.method().method() over do...end.method().method, but that might just be me.
– the Tin ManApr 5 '10 at 8:21

1

Agreed, although I prefer to assign the result of a method with block to a meaningful variable and then call another method on it like result_with_some_condition = method{|c| c.do_something || whateever}; result_with_some_condition.another_method as that just makes it a bit more easily understandable. But generally I would avoid a train wreck.
– nasJul 1 '10 at 4:22

There are two common styles for choosing do end vs. { } for blocks in Ruby:

The first and very common style was popularized by Ruby on Rails, and is based on a simple rule of single vs. multi-line:

Use braces { } for single-line blocks

Use do end for multi-line blocks

This makes sense because do/end reads badly in a one-liner, but for multi-line blocks, leaving a closing } hanging on its own line is inconsistent with everything else that uses end in ruby, such as module, class & method definitions (def etc.) and control structures (if, while, case, etc.)

The second, less-frequently seen style is known as semantic, or "Weirich Braces", proposed by the late, great rubyist Jim Weirich:

Use do end for procedural blocks

Use braces { } for functional blocks

This means that when the block is evaluated for its return value, it should be chainable, and the {} braces make more sense for method chaining.

On the other hand, when the block is evaluated for its side-effects, then the return value is of no consequence, and the block is just "doing" something, so it does not make sense to be chained.

This distinction in the syntax conveys visual meaning about the evaluation of the block, and whether or not you should care about its return value.

For example, here the return value of the block is applied to every item:

items.map { |i| i.upcase }

However, here it's not using the block's return value. It's operating procedurally, and doing a side-effect with it:

items.each do |item|
puts item
end

Another benefit of the semantic style is that you don't need to change braces to do/end just because a line was added to the block.

As an observation, coincidentally functional blocks are frequently a one-liner, and procedural blocks (e.g. config) are multi-line. So, following the Weirich style ends up looking almost the same as the Rails style.