以下代码会导致错误
示例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会导致错误吗?
由于
答案 0 :(得分:4)
您的问题发生在:
params[:id] == '2' || params.has_key? :id
可以简化为:
:foo || some_method :bar
导致相同的错误。
之间原则上这个表达式是不明确的(:foo || some_method) :bar (1)
和
:foo || (some_method :bar) (2)
当表达式不明确时,它会被其他因素解决。一个因素,运算符优先级在这里没有说明消除(1)和(2)之间的歧义。下一个因素是线性顺序。由于||
出现在相关表达式中的参数应用()
(省略)之前,因此前者适用于后者。因此,表达式被解释为
(1)。由于(:foo || some_method)
将被解析为表达式,因此会有两个表达式彼此相邻。这是不合语法的,就像:
:baz :bar
是不合语法的。
实际上,如果您将订单切换为:
some_method :bar || :foo
然后,它将被解释为
(some_method :bar) || :foo
出于同样的原因,语法错误将消失。
此外,当您通过明确使用括号来指示参数应用程序来解决歧义:
:foo || some_method(:bar)
然后没有需要解决的歧义,语法错误消失了。
答案 1 :(得分:1)
您的: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
另请查看this question以获取有关Ruby符号的更多信息。
答案 2 :(得分:0)
它与Ruby
如何评估if
语句有关。
示例1如
if (params[:id] == '2' || params.has_key?) :id
可解决意外的符号错误,因为您可以看到syntax error, unexpected tSYMBEG
。
答案 3 :(得分:0)
正如家伙所说......解析器不假设该符号是has_key的参数?方法
您可以通过明确编写括号
来绕过错误if params[:id] == '2' || params.has_key?(:id)