6

強調したいのは、Ruby 1.9.3 インタープリターによってオペレーターが実際にどのように展開されるかを探していることであり、その振る舞いに基づいてどのように展開されるかではありません。私が本当に望んでいるのは、実際のインタープリターのソースを理解した人です。この質問を調べているように見える唯一のリソースは古くなっています: " A short-circuit (||=) edge case ".||=

上記のリソースは、 1.9 より前のバージョンのインタープリターではx ||= ytoの「公式」展開がx = x || y不正確であるか、バグが多かったことを示唆しているようです。いずれにせよ、示されているエッジ ケースは平滑化されているようです。上記のリソースは、x || x = yまたはx 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

2

編集:この投稿は仕様に関するものです。コメントを読んで、やや理想的ではない「実装ストーリー」を入手してください


Ruby ドラフト仕様 (PDF) セクション 11.4.2.3.2では、かなり具体的に定義されています(解釈がかなり難しい場合でも)。c ||= 3; を使用して (理論的にはやや緩い) 例を実行してみましょう。

a) 変数を変数参照として評価する (11.5.4 を参照)。V を結果の値とします。

V は次の値に設定されます。c

b) operator-expression または method-invocation-without-parentheses を評価します。W を結果の値とします。

W を に設定し3ます。

c) OP を代入演算子の代入演算子名とする。

OPはに設定されています||

d) X を V OP W 形式の演算子式とする。

X に設定されc || 3ます。

e) I を省略変数代入式または省略変数代入文の変数とする。

を参照するように設定されていcます。

f) 変数が I で演算子式が X である単一変数代入式 (11.4.2.2.2 を参照) を評価します。

c = c || 3評価されます。

g) abbreviated-variable-assignment の値は、評価の結果の値です。

割り当ての結果は です3

言い換えれば、拡張c = c || 3は (1.9 より前のようなバグを除いて) 正しいです。

于 2012-09-05T18:41:13.843 に答える