The expression { a: 1 }
is not a problem,
but Rubocop's point( Lint/Syntax: unexpected token tCOLON(Using Ruby 3.1 parser; configure using TargetRubyVersion parameter, under AllCops)
) appears in the expression
puts { a: 1 }
.
Does anyone know why this statement is against the rules? If you have a reference, I would appreciate it if you could also give me the URL of it.
I use rubocop version 1.24.1 and set TargetRubyVersion
in .rubocop.yml
. ruby versions 2.7, 3.0 and 3.1 were all tested with the same result.
CodePudding user response:
Braces in Ruby are used for two things: blocks and hashes. And the Ruby parser isn't going to perform infinite lookahead to determine which one it's looking at. If the current syntactic context accepts a block, Ruby assumes the thing you've given it with braces is a block.
puts { a: 1 }
First, we parse puts
. It's an identifier, and it's not a local variable, so we'll assume it's a method on the current (main
) object. Now we see {
. It could be either a hash or a block. And we just parsed an identifier starting a function call, so a block would make sense here. Let's parse it as a block.
Next we see a
. Okay, that's fine. A block with no arguments, and we've got an identifier called a
. Again, it's not a local variable, so it must be a method on main
. Then we see :
and that doesn't work. There's no way a :
can appear at this point in the syntax, so it's an error. Ruby does not go back and try the "hash" option; it's already committed completely to parsing a block, and that failed.
To call puts
with a single hash argument, use parentheses to disambiguate.
puts({ a: 1 })