我最近在使路径正常工作时遇到了一些问题。解决方案结果很简单,但我遇到了一个意想不到的问题,阻止了我进入它。包含在erb模板中的以下行完美运行:
<%= button_to "Confirm delivery", delivery_confirm_path( @delivery ) %>
这个没有:
<%= button_to "Confirm delivery", delivery_confirm_path ( @delivery ) %>
在这种情况下,似乎不允许在左括号之前的间距。我得到的错误是:
/app/views/deliveries/_delivery_buttons.html.erb:22: syntax error,
unexpected tLPAREN_ARG, expecting keyword_do or '{' or '('
...ivery", delivery_confirm_path ( @delivery ) );@output_buffer...
... ^
有人可以解释为什么会导致错误吗?
编辑:有关信息,这是Windows 1.9 64位上的Ruby 1.9.2和Rails 3.0.9
答案 0 :(得分:7)
任何在参数列表括号前放置空格的人都会得到他们应得的东西,我说!
问题是它在第二个例子(括号前的空格)中关闭了对button_to
的调用,并且不知道下一步该做什么。
答案 1 :(得分:4)
我不确定这是否是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
。
分组有什么用?
一个原因是为了提高可读性。您可能会认为使用此表达式中的parens更容易理解,而不是:
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
示例有点人为,因为ruby不允许删除前面的空格。 (我不确定原因,因为&&
被允许而不是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
答案 2 :(得分:-1)
您不能在函数及其参数之间使用空格。实际上,在rails中,解析器引擎在调用之后就想要函数的括号。 这就是铁轨的生命。
希望能帮到你。
谢谢