Ruby on rails Ruby中括号的间距

Ruby on rails Ruby中括号的间距,ruby-on-rails,ruby,Ruby On Rails,Ruby,我最近遇到了一些问题,无法使路径正常工作。解决方案原来很简单,但我遇到了一个意想不到的问题,使我无法着手解决。erb模板中包含的以下行非常有效: <%= button_to "Confirm delivery", delivery_confirm_path( @delivery ) %> 有人能解释为什么这会导致错误吗 编辑:请注意,这是Ruby 1.9.2和Rails 3.0.9,在64位Windows 7上,不能在函数及其参数之间使用空格。事实上,在rails中,解析器引擎希望

我最近遇到了一些问题,无法使路径正常工作。解决方案原来很简单,但我遇到了一个意想不到的问题,使我无法着手解决。erb模板中包含的以下行非常有效:

<%= button_to "Confirm delivery", delivery_confirm_path( @delivery ) %>
有人能解释为什么这会导致错误吗


编辑:请注意,这是Ruby 1.9.2和Rails 3.0.9,在64位Windows 7上,不能在函数及其参数之间使用空格。事实上,在rails中,解析器引擎希望函数的括号正好在调用之后。 这就是rails的生活

希望能帮助你


谢谢

我说,任何在参数列表括号前加空格的人都应该得到他们应得的


问题是,在第二个示例中(括号前的空格),它结束了对
按钮的调用,并且不知道下一步该怎么做。

我不确定ruby的解析器是否真的是这样工作的,但我这样想:
传递之前的逗号\u confirm\u路径
的优先级高于括号,除非你把空间处理掉

解析器将方法调用视为:

button_to "Confirm delivery", delivery_confirm_path
换句话说,
delivery\u confirm\u path
被解析为不带参数的方法调用。但是解析器会看到悬空的
(@delivery)
,并且它的语法无效,因为它遵循
按钮\u来调用
方法。就好像你有一个无效的语法:

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
。如果括号前有空格,则将显示解释为分组表达式的
警告:(…)

这两行在语法上是等价的:

foo (1)
foo 1
这是因为作为分组表达式的
(1)
只是
1

分组有什么好处

一个原因就是为了更具可读性。你可能会认为在这个表达式中,用PAREN更容易理解:
foo (2 + 3)
foo 2 + 3
另一个原因是优先权。假设我有一个低优先级的操作,比如
操作符。因为方法调用具有更高的优先级,
在调用之后进行计算。这将打印
[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
但是请注意,
示例有些做作,因为ruby不允许删除前面的空格。(我不知道为什么,因为允许使用
和&
而不是
)但是你明白了

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

似乎是语言的局限。你找到了一个解决办法,我不明白你为什么要把它当作一个问题。@Gazler+1,与Matz自己的一篇文章的极好链接!仅仅是因为我没有意识到这是语言的一个局限性——我想它一定是与按钮_to function call混淆了,或者是我在错误消息中看到的erb内部的某些东西。我几乎从来没有像这样在括号前加空格,所以我在几个月的Ruby工作中没有注意到这个限制,但我整天都在和这样做空格的人一起工作,所以在我看来这看起来不像是一个错误。这是不正确的;记录了您可以使用和不能使用空间的情况<例如,code>put(“hi”)
,可以很好地工作。在Ruby和Rails中,您可以在函数及其参数之间使用空格。所有这些都产生相同的输出:
放置“hi”
放置(“hi”)
放置(“hi”)
放置“hi”
上述示例仅适用于单个参数,因为它与
放置((“hi”)等效
put(“hi”、“bye”)
是一个语法错误。在您对Sebastien答案的评论中,您提到当您可以使用空格时,会记录它。你有它的链接吗?Gazler的评论链接到Matz的一个非常明确的答案,但我还没有看到在哪里有文件证明间隔很重要。@asc99c我指的是O'Reilly的书《Ruby编程语言》,第2.1.6.2节,“空间和方法调用”。一般规则:不要在方法及其开头部分前面加空格:)书中没有说明原因,并提供了一个不同的例子。
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