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

cbm*_*ica 6 ruby

我想强调,我在寻找实际的方式||=操作由红宝石1.9.3解释,它不是如何扩大出现基于其行为进行扩展.我真正希望的是那些已经找到了实际翻译来源的人,这是我可能不满意的任务.我已经发现了一种审查这个问题的唯一资源是过时的:" 甲短路(|| =)边缘情况 ".

我上面提到的资源似乎表明的"官方"扩展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 
Run Code Online (Sandbox Code Playgroud)

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

Joa*_*son 2

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


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

a) 将变量作为变量引用进行计算(见 11.5.4)。令 V 为结果值。

V 设置为以下值c

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

W 设置为3

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

OP 设置为||

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

X 设置为c || 3

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

我设置为参考c

f) 计算单变量赋值表达式(参见 11.4.2.2.2),其中变量为 I,运算符表达式为 X。

c = c || 3被评估。

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

赋值的结果是3

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

  • @echristopherson:这就是问题所在。`||=` 和 `&&=` 是特殊情况,但它们在规范中并不是特殊情况,这使得规范或每个 Ruby 实现都是错误的。由于该规范是专门编写的,其目的是所有现有的 Ruby 实现都应该自动兼容而无需更改,因此该错误显然存在于规范中。 (5认同)