'[1 + x [1]]'为什么'[fx [1]]'不合语法?

chi*_*ers 5 ruby syntax

对于数组x,以下是语法表达式:

  • puts x[1]
  • [puts(x[1])]
  • [1 + x[1]]

但是这个:

  • [puts x[1]]

无法解析:

syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('
Run Code Online (Sandbox Code Playgroud)

为什么解析器无法找出这种语法?

Max*_*Max 9

我相信这种解析行为是有意的 - 而不是错误.这是Ruby的一个不幸的副作用,允许省略括号.当然,这段代码很好:

def f x, y=0
  x + y
end

f 2    # 2
f 2, 3 # 5
Run Code Online (Sandbox Code Playgroud)

但是这段代码的结果是什么?

[f 2, 3]
Run Code Online (Sandbox Code Playgroud)

[2,3]还是[5]?为了使语法分析器能够处理这个代码,需要理解该方法的优点.但是因为Ruby是动态的,在实际执行方法调用之前无法确定.

设计人员在解析过程中选择了(仍然令人惊讶,但是)容易修复的错误,而不是允许在运行时肯定会导致令人惊讶的情况的模糊情况.

注意:你仍然可以争辩说,在它是最后一个元素的情况下,没有歧义

[3, f 2]
# should be [3, 2]
Run Code Online (Sandbox Code Playgroud)

但我可以想象,如果Ruby让我写下来然后在我向数组的末尾再添加一个元素时出现语法错误,我会把头发拉出来.我可以理解决定不允许在数组中省略括号.

  • 值得注意的是(也许)有些情况下,如果你向数组添加另一个元素,Ruby会给你一个语法错误,这确实令人沮丧:`a = [2,foo :: bar] #fine`而` a = [2,foo :: bar,3]#syntax error` (3认同)

tad*_*man 6

在Ruby中,您通常可以但不总是省略方法调用的括号.你找到了一个你不能的案例.有时候,Ruby很难理解你想要什么,你必须更具体.

这里的有效表示法是:

[puts(x[1])]
Run Code Online (Sandbox Code Playgroud)

虽然puts一如既往地回归nil,但这真是一件奇怪的事情.