Ruby on Rails – Ruby运算符优先级 – 括号
以下代码导致错误
例1
if params[:id] == '2' || params.has_key? :id abort('params id = 2 or nothing') end syntax error, unexpected tSYMBEG, expecting keyword_then or ';' or '\n' if params[:id] == '2' || params.has_key? :id
但是,切换条件语句|| 添加括号可以100%工作。
例2
if params.has_key? :id || params[:id] == '2' abort('params id = 2 or nothing') end
例3
if (params[:id] == '2') || (params.has_key? :id) abort('params id = 2 or nothing') end
任何人都可以向我解释为什么示例1会导致错误?
谢谢
你的问题发生在:
params[:id] == '2' || params.has_key? :id
可以简化为:
:foo || some_method :bar
这会导致同样的错误。 这个表达原则上是模糊的
(:foo || some_method) :bar (1)
和
:foo || (some_method :bar) (2)
当表达式不明确时,它会被其他因素解决。 一个因素,运算符优先级在这里没有说明消除(1)和(2)之间的歧义。 下一个因素是线性顺序。 自||
出现在有问题的表达式中的参数application ()
(省略)之前,前者适用于后者。 因此,表达式被解释为(1)。 由于(:foo || some_method)
将被解析为表达式,因此会有两个表达式彼此相邻。 这是不合语法的,就像:
:baz :bar
是不合语法的。
实际上,如果您将订单切换为:
some_method :bar || :foo
然后,它将被解释为
(some_method :bar) || :foo
出于同样的原因,语法错误将消失。
此外,当您通过显式使用括号来指示参数应用程序来解决歧义时:
:foo || some_method(:bar)
然后没有需要解决的歧义,语法错误消失了。
你的:id
是Ruby中的一个符号。
a = {'id' => 'a', 'value' => 'value'} a.has_key? 'id' => true a.has_key? :id => false
所以你需要改变你的代码:
if params[:id] == '2' or params.has_key? 'id' abort('params id = 2 or nothing') end
注意:如果要在检查值之前使用此代码检查密钥更有意义。
注2:经测试:
params = {'id' => 'a', 'value' => 'value'} if params[:id] == '2' or params.has_key? 'id' abort('params id = 2 or nothing') end
和Ruby 2.0.0
另请查看此问题以获取有关Ruby符号的更多信息。
它与Ruby
如何评估if
语句有关。
例1就像if (params[:id] == '2' || params.has_key?) :id
这可以解决意外的符号错误,因为您可以看到syntax error, unexpected tSYMBEG
。
正如家伙所说……解析器不假设该符号是has_key的参数? 方法
您可以通过显式编写括号来绕过错误
if params[:id] == '2' || params.has_key?(:id)