What is the difference or value of these block coding styles in Ruby?
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}"
}
Solution 1:
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.
Solution 2:
According to the "Pickaxe" book (I'm looking at the 2nd edition here), 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. Thedo
form will bind to the invocation.
See also p.168 for an example.
Solution 3:
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.