きしもとです

とり急ぎ最初の急所のみ。

On Tue, 13 Jan 2015 12:40:12 +0900
"5.5" <5.5 / moji.gr.jp> wrote:
> 5.5 です。
> 
> Qiita に知ったかぶりして投稿したら思い切り間違いを書いてしま
> ったので,急ぎ修正したく,恥を忍んでお尋ねいたします。
> http://qiita.com/scivola/items/bb2934941040dab14acd
> 
> 
> るりま
> 
> http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2foperator.html#selfassign
> 
> に従えば x ||= 1 は x || (x = 1) のはずですが,x が未定義のと
> き後者は NameError になります。
> 
> よって,るりまが部分的に誤っているのだろうと思いますが,では
> 本当はどうなのでしょうか。

世間の用法としては揺れがあるのですが、私はsyntactic sugarという
用語を「ソースコードをそのように書き換えたのと全く同じになるもの」
と定義しています。

そしてその意味では、
「るりまのこの記述は、syntactic sugarだと言っているのではない」
ということになります。(るりまの修正の必要はあるかもしれません)

未定義によるNameErrorは実行ではなく、字面上の理由による、という
点はご指摘の通りですが、実際のところたとえば、

x = 1

の x をrubyが読んだ時点では未定義なわけですから、ある程度まで読み進め
ながら判断される、ということで、「微妙なところ」とでも言うしかないで
しょう。(似たような、変数の宣言が必要ない他の言語でも、この点は微妙
なのではないかと想像します)

そして、るびまのちょっと変わった記述の理由(さかもとさんのご指摘の
ような、他の演算子と同様な x = x || 1 としていない理由)は、
推測ですが、|| は他の演算子と違い、短絡評価のために2度目以降は代入が
起きないためと思われます(次のような感じに違っています)。

$ cat hoge.rb
trace_var(:$a) {p "$a assigned"}
trace_var(:$b) {p "$b assigned"}

$a ||= 1
$a ||= 1

$b |= 1
$b |= 1

$ ruby21 hoge.rb
"$a assigned"
"$b assigned"
"$b assigned"