简体   繁体   English

在Ruby中用括号括起来

[英]Spacing around parentheses in Ruby

I've recently had some problems getting a path working properly. 我最近在使路径正常工作时遇到了一些问题。 The solution turned out to be simple but I had an unexpected problem that stopped me getting to it. 解决方案结果很简单,但我遇到了一个意想不到的问题,阻止了我进入它。 The following line, included in an erb template, works perfectly: 包含在erb模板中的以下行完美运行:

<%= button_to "Confirm delivery", delivery_confirm_path( @delivery ) %>

This one doesn't: 这个没有:

<%= button_to "Confirm delivery", delivery_confirm_path ( @delivery ) %>

It seems spacing before the opening parenthesis is not allowed in this case. 在这种情况下,似乎不允许在左括号之前的间距。 The error I get is this: 我得到的错误是这样的:

/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...
...                               ^

Can anybody explain why this causes an error? 任何人都可以解释为什么会导致错误吗?

EDIT: for info, this is Ruby 1.9.2 and Rails 3.0.9, on Windows 7 64-bit 编辑:对于信息,这是在Windows 7 64位上的Ruby 1.9.2和Rails 3.0.9

Anyone that puts a space before a parameter-list parentheses gets what they deserve, I say! 我说,任何在参数列表括号前放置空格的人都能得到他们应得的东西!

The problem is that it's closing out the call to button_to in the second example (space before the parentheses) and doesn't know what to do next. 问题是它在第二个例子(括号前的空格)中关闭了对button_to的调用,并且不知道下一步该做什么。

I'm not sure if this is how ruby's parser actually works, but I think of it this way: The comma before delivery_confirm_path has higher precedence than the parentheses, unless you get rid of the space. 我不知道这是否是Ruby的语法分析器实际上是如何工作的,但我认为它是这样的:前逗号delivery_confirm_path比括号更高的优先级,除非你摆脱空间。

The parser sees the method call as this: 解析器将方法调用视为:

button_to "Confirm delivery", delivery_confirm_path

In other words, delivery_confirm_path is parsed as a method call without arguments. 换句话说, delivery_confirm_path被解析为没有参数的方法调用。 But then the parser sees the dangling ( @delivery ) and it's not valid syntax because it follows the button_to method call. 但是然后解析器看到悬空( @delivery )并且它不是有效的语法,因为它遵循button_to方法调用。 It's as though you had this invalid syntax: 就好像你有这个无效的语法:

button_to("Confirm delivery", delivery_confirm_path) ( @delivery )

You can avoid the comma-precedence by doing this instead: 您可以通过执行此操作来避免逗号优先:

button_to "Confirm delivery", (delivery_confirm_path ( @delivery ))

But it's usually easier to just remove the space. 但是通常更容易删除空间。

The principle to remember is that if there's a space before parentheses with a method call, the parentheses are used as grouping, and not as method-call parentheses. 要记住的原则是,如果括号前面有一个带方法调用的空格,则括号用作分组,而不是方法调用括号。

Here are some examples to help. 以下是一些有用的示例。 I use the following method in my examples: 我在我的例子中使用以下方法:

def foo(*args); puts args.inspect; true; end

If you're on ruby 1.9, I suggest turning on warnings when running the examples: $-w = true . 如果您使用的是ruby 1.9,我建议在运行示例时启用警告: $-w = true This will display warning: (...) interpreted as grouped expression if you have space before parentheses. 这将显示warning: (...) interpreted as grouped expression如果在括号前有空格,则warning: (...) interpreted as grouped expression

These two lines are syntactically equivalent: 这两行在语法上是等价的:

foo (1)
foo 1

That's because (1) as a grouped expression is just 1 . 那是因为(1)作为分组表达式只有1

What good is grouping? 分组有什么用?

One reason is just for more readability. 一个原因是为了提高可读性。 You might consider it easier to understand with parens in this expression versus without: 您可能会认为使用此表达式中的parens更容易理解,而不是:

foo (2 + 3)
foo 2 + 3

Another reasons is precedence. 另一个原因是优先权。 Let's say I have a low-precedence operation, like the and operator. 假设我有一个低优先级操作,就像and运算符一样。 Because the method call has higher precedence, the and is evaluated after the call. 因为方法调用具有更高的优先级,所以在调用之后计算and This prints [2] and returns 3 : 这打印[2]并返回3

foo 2 and 3  # same as foo(2) and 3, i.e. true and 3

But this prints [3] and returns true : 但这打印[3]并返回true

foo (2 and 3)  # the grouped expr returns 3, which is passed to foo

Note, however that the and example is somewhat contrived, because ruby doesn't allow removal of the preceding space. 但是请注意,这个and例子有点人为,因为ruby不允许删除前面的空格。 (I'm not sure why, since && is allowed instead of and .) But you get the idea. (我不确定为什么,因为&&被允许而不是and 。)但是你明白了。

foo(2 and 3)  # syntax error - but why?? I still don't understand.
foo(2 && 3)   # works fine. This is strangely inconsistent.

This demonstrates that removing the space before a method call will elevate the method-call precedence above a comma: 这表明在方法调用之前删除空格会将方法调用优先级提升到逗号以上:

foo 1, foo 2  # syntax error; the 2 is dangling
foo 1, foo(2)  # ok

Another gotcha is argument lists. 另一个问题是参数列表。

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

You can't use a space between a function and its arguments. 您不能在函数及其参数之间使用空格。 In fact, in rails the parser engine wants the parenthesis of the function just after its call. 实际上,在rails中,解析器引擎在调用之后就想要函数的括号。 That's the rails' life. 这就是铁轨的生命。

Hope to help you. 希望能帮到你。

Thank you 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM