为什么这个ruby方法调用中的空间有意义?

Sam*_*man 5 ruby

我正在Rails应用程序中编写jsonify视图.我有:

json.samba_secrets_present(not @idp_ad_info.samba_secrets.nil?)
Run Code Online (Sandbox Code Playgroud)

这会产生语法错误:

app/views/idp_ad_infos/show.jsonify:7: syntax error, unexpected tIVAR, expecting '(' 
Run Code Online (Sandbox Code Playgroud)

然而,

json.samba_secrets_present (not @idp_ad_info.samba_secrets.nil?)
Run Code Online (Sandbox Code Playgroud)

工作良好.我原以为第一个方法samba_secrets_presentJsonify::Builder使用第一个参数调用对象上的方法not idp_ad_info.samba_secrets.nil?.为什么空间有意义?

Ari*_*iao 5

puts(not true)  #=> error
puts (not true) #=> false, CASE 2
puts(not(true)) #=> false
Run Code Online (Sandbox Code Playgroud)

Ruby允许您省略用于调用方法的括号.通常,如果只有一个方法调用,则可以省略括号.但是,当方法调用位于另一个方法调用的参数位置时(通常情况下,请参见"更新"部分中的特殊情况),您不能省略它,因为这会引入歧义.请考虑以下示例:

puts(not true, false)
puts(some_method arg1, arg2)
Run Code Online (Sandbox Code Playgroud)

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

CASE 2作为一个例子,这是解释为:

puts( (not false))
Run Code Online (Sandbox Code Playgroud)

你可以写:

puts (not false), true, (not true)
Run Code Online (Sandbox Code Playgroud)

他们都是争吵puts.

一些参考:位置参数

更新: toro2k评论说puts(system 'ls')有效.这是因为system接受*args将获取所有其余参数.外部方法不会有任何参数,绝对:).结果,在这种情况下没有歧义.

def a *args
  args
end
p(a 1, 2, 3, 4) #=> [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

但是,我会投票使用必要的括号编写更清晰的代码,以使代码更具可读性.