How to do "do" blocks

How come this works:

collection_of_objects = []
10.times do
collection_of_objects << MyObject.create
end

But this doesn’t:

collection_of_objects = []
10.times do { collection_of_objects << MyObject.create }

I didn’t understand there was ANY difference between the two syntaxes
really. Can someone explain to me the finer points?

Take the “do” out of the statement when passing a block in {}:

collection_of_objects = []
10.times {collection_of_objects << MyObject.create}

:slight_smile:

On 9/28/07, Daniel T. [email protected] wrote:

10.times do { collection_of_objects << MyObject.create }

I didn’t understand there was ANY difference between the two syntaxes
really. Can someone explain to me the finer points?

The reason is that “do” starts a block, and then inside the block the
{} are parsed as a hash literal:

irb(main):001:0> collection_of_objects = []
=> []
irb(main):002:0> 10.times do { collection_of_objects << MyObject.create
}
irb(main):003:1> end
SyntaxError: compile error
(irb):2: odd number list for Hash
from (irb):3
from :0

You have to use only one form of block, either do…end or {}. The
convention seems to be to use do…end for multiline blocks, while {}
is used for one-liners.

irb(main):005:0> 10.times { collection_of_objects << Array.new }
=> 10
irb(main):006:0> collection_of_objects
=> [[], [], [], [], [], [], [], [], [], []]

Regards,

Jesus.

On 9/28/07, Daniel T. [email protected] wrote:

http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc

In the first post, one of the commenters asks:

As for using {} only when returning a value, doesn’t every statement return a
value (in your example, the array with it’s elements capitalised and reversed)?

And although he’s wrong, the code in question:
i.capitalize!
is in-place changing the variable of course… but his point is still
valid. Anyone want to weigh in on this?

I’m fairly new to Ruby, and still trying to accomodate my style
(coming from java it’s taking me a while to use do…end, my fingers
type the { automatically :-), but I’m pretty sure I’ve read many times
here what I said above, and those articles also imply that’s the more
widely accepted answer to that question.

I can’t comment on other people’s uses of this. Maybe more
knowledgeable people here could chime in?

Jesus.

Well thanks fellas… that makes good sense.

You have to use only one form of block, either do…end or {}. The
convention seems to be to use do…end for multiline blocks, while {}
is used for one-liners.

However, there’s some lines of thought on the internet that have a
different idea. What do you think of the idea that it’s not “one line
vs. multiline” but “returns a value vs. doesn’t return a value”.

Here’s the two posts I’m talking about:
http://objo.com/2007/6/28/ruby-style-ruby-do-end-versus
http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc

In the first post, one of the commenters asks:

As for using {} only when returning a value, doesn’t every statement return a
value (in your example, the array with it’s elements capitalised and reversed)?

And although he’s wrong, the code in question:
i.capitalize!
is in-place changing the variable of course… but his point is still
valid. Anyone want to weigh in on this?

However, there’s some lines of thought on the internet that have a
different idea. What do you think of the idea that it’s not “one line
vs. multiline” but “returns a value vs. doesn’t return a value”.

All Ruby blocks (and methods) return a value. They return the value
of the last statement in the block.
But only if you explicitly use it.
Assign it to something, or use return if you want it to be obvious.

The convention is simply
{} for one-line
do-end for multi-line

You don’t have to follow these rules. It is up to you.

On 9/28/07, Daniel T. [email protected] wrote:

Here’s the two posts I’m talking about:
valid. Anyone want to weigh in on this?
http://talklikeaduck.denhaven2.com/articles/2007/10/02/ruby-blocks-do-or-brace


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Hi –

On Fri, 28 Sep 2007, Bertram S. wrote:

 puts "((("

(((

Not a very intuitive example I admit.

Here’s one I’ve stumbled on in real life:

irb(main):001:0> a = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):002:0> puts a.map {|e| e * 10 }
10
20
30
40
=> nil
irb(main):003:0> puts a.map do |e| e * 10 end
1
2
3
4
=> nil

David

Hi,

Am Freitag, 28. Sep 2007, 17:20:40 +0900 schrieb Tom M.:

Take the “do” out of the statement when passing a block in {}:

10.times {collection_of_objects << MyObject.create}

Yet another opportunity to mention that {} has higer
precedence than do…end.

def f
  puts "((("
  yield if block_given?
  puts ")))"
end
def g x
  puts "[[[#{x}|"
  yield if block_given?
  puts "]]]"
end

g f { puts “x” }
(((
x
)))
[[[|
]]]
g f do puts “x” end
(((
)))
[[[|
x
]]]

Not a very intuitive example I admit.

Bertram