can anybody explain why the following code aborts with an error
irb(main):186:0> print ((1..10).collect do |x| x**2 end)
SyntaxError: (irb):186: syntax error, unexpected keyword_do_block,
expecting ')'
print ((1..10).collect do |x| x**2 end)
^
(irb):186: syntax error, unexpected keyword_end, expecting $end
print ((1..10).collect do |x| x**2 end)
^
from /usr/bin/irb:12:in `<main>'
whereas following code with the same functionality works as expected ?
irb(main):187:0> print ((1..10).collect { |x| x**2 })
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]=> nil
I did believed curly-braces "{ }" can substitute "do end" arbitrarily at block definition.
I know I can "fix" the first call by omitting a space between print method and the first parenthesis, but I'm interested in an explanation why it behaves different.
The difference is precedence:
# Equivalent to puts( (1..10).map { |i| i*2 } )
> puts (1..10).map { |i| i*2 }
2
4
6
8
10
12
14
16
18
20
=> nil
# Equivalent to puts( (1..10).map ) { |i| i*2 }
> puts (1..10).map do |i| i*2 end
#<Enumerator:0x928f24>
=> nil
In the first case, the block is passed to map, and everything works properly.
In the second case, the block is passed to puts, which doesn't do anything with it. map doesn't receive a block and just returns an enumerator.
As for the syntax error, if you remove the space between print and ( everything works ;)
The difference is whether ruby is treating your parentheses as method argument delimiters, or whether it's a generic statement grouping. I'm not sure of the exact difference there but it's subtle and annoying
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With