views:

341

answers:

6

Which style is preferred? Is there a good reason for one vs. the other?

Thanks in advance!

1) cmds.each do |cmd|
   end

2) cmds.each { |cmd|
   }

Example code:

cmds = [ "create", "update", "list", "help" ]

# Block style one
#
cmds.each do |cmd|
  puts "loop1, cmd: #{cmd}"
end

# Block style two
#
cmds.each { |cmd|
  puts "loop2, cmd: #{cmd}"
}
+11  A: 

The rails team and many other rubyists prefer to use curly braces for one line blocks and do...end for multi-line ones.

The only functional difference between the two is that the precedence of a do...end block is lower than that of a {...} block.

Gordon Wilson
They are the same thing though. So when using braces, you would write it on one line like: `cmds.each { |cmd| puts "loop2, cmd: #{cmd}" }`
Squeegy
A: 

I don't think it really matters - it's just an aesthetic personal choice. Some people prefer to use the do...end version when the block needs multiple lines and the {...} version when its all on one line.

floehopper
+5  A: 

The two forms are equivalent.

The recommended style is to use the braces for one line blocks and use the "do"-"end" for multiline blocks.

Edit: Austin Ziegler pointed out (in the comment below) that the two forms have difference precedence levels: Curly braces have higher precedence. Therefore, when calling a method without parenthesis a block enclosed in {} will bind to the last argument instead of the calling method.

The following example was suggested by Austin:

def foo
    yield
end

puts foo { "hello" }

puts foo do
    "hello"
end

The first "puts" prints "hello": foo gets called returning "hello" which is the argument to puts.

The second bails with an error:

in `foo': no block given

Since in this case the do-end block binds to the puts method.

Thanks again to Austin for clearing this up.

nimrodm
No, they're not. def foo yield end puts foo { "hello" } puts foo do; "hello"; endThe latter will throw an exception. The former will not (and it will print "hello"). { } binds to #foo; do/end binds to #puts.
Austin Ziegler
Thanks for pointing this out. I have edited the answer giving you the credit. You should have really added your own answer so that the original poster could mark it as the correct answer.
nimrodm
+1  A: 

Most often, style 1 is used for multiple-line blocks and style 2 is used for one-liners.

The do…end syntax closely resembles other Ruby control structures (if, def, class), so using that for blocks keeps the appearance of your code consistent and clear. But it doesn't work well for one-liners, which is why the brackets version is preferred there.

Chuck
+5  A: 

Gordon's answer is "the Ruby Way," and although it is a common practice to put one line in braces, it is not required.

Also note the ease with which one can act on the resulting value:

cmds.each do |cmd| cmd.upcase! end.sort

# Now, cmds = ["CREATE", "HELP", "LIST", "UPDATE"]

Although you might already see how {} is more readable here, and therefore preferred if anyone else is going to see your code:

cmds.each { |cmd| cmd.upcase! }.sort
zandev
zandev, Thanks for the extra tip on 'end.sort'
John Burley
+5  A: 

According to the "Pickaxe" book, Gordon's correct: the only difference is precedence:

p.356 (my italics) :

Braces have a high precedence; do has a low precedence. If the method invocation has parameters that are not enclosed in parentheses, the brace form of a block will bind to the last parameter, not to the overall invocation. The do form will bind to the invocation.

See also p.168 for an example.

Mike Woodhouse