3 ms·
This is one of those gotchas with Ruby's syntax for blocks clashing with Ruby's syntax for hash literals. I'm not familiar with the details of precisely why Rub
by jashkenas 16y ago
This is one of those gotchas with Ruby's syntax for blocks clashing with Ruby's syntax for hash literals. I'm not familiar with the details of precisely why Ruby's parser handles some cases, and not others, but I bet there's a special case for assignment -- you can't ever assign a block literal, so it has to be a hash...
Here are some of the variants:
method({ ... }) # hash
method { ... } # block, even though a hash would be possible.
method = { ... } # hash
method a, b, :c => d # implicit hash
method a, b { ... } # SyntaxError
method(a, b) { ... } # block
Only #2 in that list is really a problem, because there are situations where you'd legitimately like to use both.
- andrewvc 16y agoThis is one reason why I always use parens on my method calls. Some rubyists find it cluttering, yeah, but I think it makes reading code easier. The other one to watch out for is precedence of {} vs do; end. Example: > x = [1,2].map do |i| i*2; end => [2, 4] > puts [1,2].map do |i| i*2; end 1 2 => nil > puts [1,2].map { |i| i*2} 2 4 => nil
- jashkenas 16y agoAgreed. It's why we've tried to be careful with lambda/hash/call syntax in CoffeeScript, especially where some of it is optional, and can be left out. For example: x = [1, 2].map (i) -> i * 2 ... is without optional parens. x = [1, 2].map((i) -> i * 2) ... is with them. configure start: 10, end: 25 ... is the syntax for calling a method and passing an implicit hash -- and with the optional braces and parens added, it's closer to JavaScript... configure({start: 10, end: 25})
- jimweirich 16y ago#5 is also not a syntax error. Rather b is interpreted as a method and the block is associated with it.