6

我想强调一下,我正在寻找 Ruby 1.9.3 解释器扩展运算符的实际方式,而不是根据其行为扩展它的方式。我真正希望的是有人了解实际的解释器来源,遗憾的是我可能无法完成这项任务。我发现的唯一可以检查这个问题的资源已经过时了:“ A short-circuit (||=) edge case ”。||=

我上面提到的资源似乎表明 to 的“官方”扩展在 1.9 之前的解释x ||= yx = x || y版本中要么不准确,要么存在错误。无论如何,所指示的边缘情况似乎已被平滑。上述资源声称x || x = yx or x = y“更准确”。然而,这些都不正确,因为它们在x以前未声明的全局变量时不起作用:

[11:04:18][****@asha:~]$ irb
1.9.3-p194 :001 > a || a = 3
    NameError: undefined local variable or method `a' for main:Object
1.9.3-p194 :002 > b or b = 3
    NameError: undefined local variable or method `b' for main:Object
1.9.3-p194 :003 > c = c || 3
    => 3 

因此,就这些示例而言,至少在 1.9.3 中,x = x || y扩展似乎是正确的。但是,为了重申我的原始观点,我真的很希望看到一些真正权威的来源解决这个问题,好吧,权威而不是像我(和其他人)所做的那样轶事。

4

2 回答 2

3
x ||= y

是一种简写形式

x || x = y

如果xis notnilxis not false,则由于运算符的短路评估,分配将有位置||

于 2014-01-21T18:36:13.810 回答
2

编辑:这篇文章是关于规范的,阅读评论以获得不太理想的“实施故事”


Ruby 草案规范 (PDF)第11.4.2.3.2 节相当明确地定义了它(即使相当难以解释);让我们用 c ||= 3 做一个(理论上有点松散的)例子;

a) 将变量评估为变量引用(见 11.5.4)。令 V 为结果值。

V 设置为c

b) 评估运算符表达式或无括号的方法调用。令 W 为结果值。

W 设置为3

c) 令 OP 为 assignment-operator 的 assignment-operator-name。

OP设置为||

d) 令 X 为 V OP W 形式的运算符表达式。

X 设置为c || 3

e) 令 I 为缩写变量赋值表达式或缩写变量赋值语句的变量。

我设置参考c

f) 计算一个单变量赋值表达式(见 11.4.2.2.2),它的变量是 I,操作符表达式是 X。

c = c || 3被评估。

g) abbreviated-variable-assignment 的值是评估的结果值。

赋值的结果是3

换句话说,扩展c = c || 3是正确的(不包括 1.9 之前的错误)。

于 2012-09-05T18:41:13.843 回答