Reputation: 1294
I tried to run this simple code in an IRB session, but I got this error:
[9] pry(main)> puts {x: 1}
SyntaxError: unexpected ':', expecting '}'
puts {x: 1}
^
I know that I can run the same code like this:
[12] pry(main)> y = {x: 1}
=> {:x=>1}
[13] pry(main)> puts y
{:x=>1}
or:
[14] pry(main)> puts "",{x: 1}
{:x=>1}
What is that the problem in the first case?
Upvotes: 0
Views: 92
Reputation: 369420
Curly braces can denote either a block literal or a Hash
literal. In this case, it is interpreted as a block literal, and x: 1
is not a syntactically valid Ruby expression.
You can provide the argument list with parentheses to resolve this ambiguity:
puts({x: 1})
Or alternatively, Ruby allows you to leave out the curly braces if the last argument to a method is a Hash
:
puts(x: 1)
And in that case, you can again leave out the parentheses, because there is no confusion with a block:
puts x: 1
Your last example works, because the comma tells the parser that the argument list isn't finished yet and what follows couldn't possibly be a block.
Upvotes: 4
Reputation: 704
Ruby thinks your passing a block. For passing a hash, try:
puts({x: 1})
or
puts(x: 1)
Upvotes: 0
Reputation: 23556
In the first case {}
is parsed as a block. In the second it is parsed as a hash.
Example:
def foo(opts = nil, &block)
p opts
p block
end
foo { 'a' } #=> nil #<Proc:0x007f12144f7f68@(pry):12>
foo({a: 'a'}) #=> {:a=>"a"} nil
foo a: 'a' #=> {:a=>"a"} nil
Upvotes: 1