为什么在这个 Ruby 方法调用中空格很重要?

5

我正在编写一个Rails应用程序中的jsonify视图。我有:

json.samba_secrets_present(not @idp_ad_info.samba_secrets.nil?)

这会产生一个语法错误:

app/views/idp_ad_infos/show.jsonify:7: syntax error, unexpected tIVAR, expecting '(' 

然而,(下文无翻译要求)
json.samba_secrets_present (not @idp_ad_info.samba_secrets.nil?)

运行良好。我本来以为第一个方法调用是在Jsonify::Builder对象上调用samba_secrets_present方法,第一个参数为not idp_ad_info.samba_secrets.nil?。为什么空格很重要?


1
也许这是旧的“not”运算符错误,例如puts(not true)会失败,但puts((not true))可以正常工作。我忘记了这一点。(或者根据答案所示,这不是一个错误,而是一个解析问题?) - Dave Newton
1
完全没有关系,但是使用 not 而不是 ! 的用例是什么?另一个 SO 回答说 ! 有最高的优先级,而 not 有最低的优先级之一...但我仍然在寻找使用 not 的理由。我宁愿使用括号来强制执行所需的操作顺序。 - Sunil D.
1个回答

5
puts(not true)  #=> error
puts (not true) #=> false, CASE 2
puts(not(true)) #=> false

Ruby允许你有时省略括号调用方法。通常,如果只有一个方法调用,可以省略括号。但是,在另一个方法调用的参数位置上(一般情况,请参见更新部分中的特殊情况),你不能省略括号,因为那会引入歧义。考虑以下例子:
puts(not true, false)
puts(some_method arg1, arg2)

Ruby解析器无法确定false(或arg2)是内部方法的参数还是外部puts的参数,因此会为这些情况引发错误。解析器没有运行时上下文来确定内部方法的元数,因此它不关心它是否是一元方法(如not)。

CASE 2为例,它被解释为:

puts( (not false))

而且你可以写:

puts (not false), true, (not true)

这些都是传递给puts的参数。

一些参考:位置参数

更新: toro2k评论说puts(system 'ls')可以工作。那是因为system接受*args,它会抓取所有剩余的参数。在外部方法中不会有任何参数剩余,当然 : )。因此,在这种情况下没有任何歧义。

def a *args
  args
end
p(a 1, 2, 3, 4) #=> [1, 2, 3, 4]

然而,我会投票赞成写更清晰的代码,并使用必要的括号使代码更易读。


我不明白的是:为什么 puts(not 'ls') 是语法错误,而 puts(system 'ls') 不是? - toro2k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接