在Ruby中用括号括起来
我最近在使路径正常工作时遇到了一些问题。 解决方案结果很简单,但我遇到了一个意想不到的问题,阻止了我进入它。 包含在erb模板中的以下行完美运行:
这个没有:
在这种情况下,似乎不允许在左括号之前的间距。 我得到的错误是这样的:
/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 7 64位上的Ruby 1.9.2和Rails 3.0.9
任何在参数列表括号前放置空格的人都会得到他们应得的东西,我说!
问题是它在第二个例子(括号前的空格)中关闭了对button_to
的调用,并且不知道下一步该做什么。
我不确定这是否是ruby的解析器实际上是如何工作的,但我这样想:send_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, ie 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
您不能在函数及其参数之间使用空格。 事实上,在rails中,解析器引擎在调用之后就想要函数的括号。 这就是铁轨的生命。
希望能帮到你。
谢谢