Reputation: 3081
I notice that I need to put parenthesis around arguments I pass to a Ruby method before the block. Wat is the reason for that? Boiling down to the smallest example to illustrate what I mean:
def test a
yield 100
end
test 50 { |x| x*x + 2 } # Gives an error in irb!
test(50) { |x| x*x + 2 } # Gives no error!
I didn't understand why Ruby complains about the first case. The error is along the lines of:
SyntaxError: compile error
(irb):18: syntax error, unexpected '{', expecting $end
Upvotes: 2
Views: 115
Reputation: 160551
Ruby doesn't know what you want to do with the block.
When Ruby sees:
test 50 { |x| x*x + 2 } # Gives an error in irb!
It thinks that the block is attached to 50
, which is why you get the error.
When you put 50
in parenthesis, Ruby knows that the block is not binding to 50
.
test(50) { |x| x*x + 2 } # Gives no error!
For sanity, 99.9% of the time I put the parameters inside parenthesis. I don't like having to remember the rules for binding and that ensures that Ruby will do the right thing. Also, the parenthesis help us see what are the parameters, which aids in debugging.
Upvotes: 1
Reputation: 12558
Here's an example of the possible ambiguity that would arise:
def foo(val = "default", &block)
# ...
end
Both hash and block literals are created using { ... }
So if you call foo {}
- Are you passing an empty hash to the val
parameter (with block
becoming nil
), or are you passing an empty block to the block
parameter (with val
becoming "default"
)?
Upvotes: 3
Reputation: 95242
This is related to the fact that {
...}
sometimes delimits a block and sometimes a Hash literal. Disambiguating those two uses has some odd side-effects.
If you use do
...end
, it works without the parentheses:
test 50 do |x| x*x + 2 end
Upvotes: 2
Reputation: 1599
When using the block notation, the block is run against the value to the immediate left of the opening {
. So in your first example, you are attempting to pass 50 { |x| ... }
into the test
method. Since 50
is not an Enumerable object, you are getting an error.
Upvotes: -2