我不确定这是ruby的解析器是如何工作的,但我认为它是这样的:除非你摆脱了空间,否则delivery_confirm_path
之前的逗号比括号具有更高的优先级。
解析器看到该方法调用作为这样的:
button_to "Confirm delivery", delivery_confirm_path
换句话说,delivery_confirm_path
被解析为不带参数的一个方法调用。但是,然后解析器看到悬挂的(@delivery)
,它不是有效的语法,因为它遵循button_to
方法调用。就好像你有这个无效的语法:
button_to("Confirm delivery", delivery_confirm_path) (@delivery)
你可以这样做,而不是避免逗号优先级:
button_to "Confirm delivery", (delivery_confirm_path (@delivery))
但它通常更容易只是删除空间。
要记住的原则是,如果在方括号括起来之前有一个空格,则括号用作分组,而不是方法调用括号。
下面是一些帮助的例子。我用下面的方法在我的例子:
def foo(*args); puts args.inspect; true; end
如果你在Ruby 1.9的,我建议在警告打开运行例子的时候:$-w = true
。如果括号前有空格,将显示warning: (...) interpreted as grouped expression
。
这两条线在语法上等价的:
foo (1)
foo 1
这是因为(1)
为分组表达式仅仅是1
。
分组有什么用?
一个原因是为了更好的可读性。你可能会认为这更容易与括号理解这种表达与无:
foo (2 + 3)
foo 2 + 3
另一个原因是优先级。假设我有一个低优先级操作,如and
操作符。由于方法调用的优先级较高,因此在调用后对and
进行评估。这将打印[2]
并返回3
:
foo 2 and 3 # same as foo(2) and 3, i.e. true and 3
但这打印[3]
并返回true
:
foo (2 and 3) # the grouped expr returns 3, which is passed to foo
但请注意,该and
例子是人为的,因为红宝石不允许拆除前面的空间。 (我不知道为什么,因为允许&&
而不是and
。)但你明白了。
foo(2 and 3) # syntax error - but why?? I still don't understand.
foo(2 && 3) # works fine. This is strangely inconsistent.
这表明一个方法调用之前移除所述空间将提升逗号上述方法调用的优先级:
foo 1, foo 2 # syntax error; the 2 is dangling
foo 1, foo(2) # ok
另一个疑难杂症是参数列表。
foo 2, 3 # both are treated as args to the method call
foo (2, 3) # syntax error, because "2, 3" is grouped as an expression, but is not a valid one
http://www.justskins.com/forums/ruby-1-8-space-122361.html – Gazler
似乎是一种语言的限制。你找到了一个解决方法,我不明白为什么你必须把它作为一个问题。 – Candide
@Gazler +1,与Matz自己发布的贴子联系非常好! –