官方扩展|| =条件赋值运算符

时间:2012-09-05 18:10:03

标签: ruby

我想强调一点,我正在寻找实际的方式,{1.9}解释器扩展了||=运算符,而不是出现的方式根据其行为进行扩展。我真正希望的是那些已经找到了实际翻译来源的人,这是我可能不满意的任务。我发现的唯一资源似乎已经过时了:“A short-circuit (||=) edge case”。

我上面提到的资源似乎表明,x ||= yx = x || y的“官方”扩展在1.9之前的解释器版本中是不准确或错误的。在任何情况下,指示的边缘情况似乎已经平滑。上述资源声称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扩展出现是正确的,就这些例子而言。但是,重申我原来的观点,我真的希望看到一些真正权威的消息来源解决这个问题,好吧,权威而不是像我(和其他人)所做的那样传闻。

2 个答案:

答案 0 :(得分:3)

x ||= y

的简写形式
x || x = y

如果x不是nilx不是false,则由于||运算符的短路评估,将进行分配

答案 1 :(得分:2)

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


Ruby draft spec (PDF) section 11.4.2.3.2非常具体地定义它(即使很难解释);让我们用c || = 3;

做一个(理论上有点宽松)的例子

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

V设置为c

的值

b)评估operator-expression或方法调用 - 不带括号。设W为结果值。

W设置为3

c)设OP为赋值运算符的赋值运算符名称。

OP设置为||

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

X设置为c || 3

e)让我成为abbreviated-variable-assignment-expression或abbreviated-variable-assignment-statement的变量。

我的目的是引用c

f)评估单变量赋值表达式(见11.4.2.2.2),其变量为I,运算符表达式为X.

c = c || 3已经过评估。

g)缩写变量赋值的值是评估的结果值。

作业的结果是3

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