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 になります。

よって,るりまが部分的に誤っているのだろうと思いますが,では
本当はどうなのでしょうか。


ローカル変数は,最初の代入の時点以降で定義済になるのですよね。
それから,

  x = 1 if false
  puts x #=> nil

や

  true || (x = y)
  puts x #=> nil
  puts y #=> NameError

のように,代入が実際に行われる必要は無い,と。

Ruby の処理系は,実行に先立ってこのスクリプトをまず解釈し,え
えと,構文木とかいうやつ作る。その時点で,x の有効範囲が決まっ
ている,ということですよね?

上記の二つのスクリプトで puts x のところで x が定義済みなのは
分かるのですが,

  x = x
  puts x #=> nil

だとか,

  x = (y = x)
  puts x, y #=> nil, nil

といったスクリプトでも NameError にはなりません。
ということは,この二つのスクリプトで 1 行目は x や y が定義済
みなのですよね?

それなのに

  x || (x = 1) #=> NameError
  puts x

がダメなのは,どういうことなんでしょうか。


そして,x ||= 1 は,本当は何なんでしょうか。

-- 
5.5 / moji.gr.jp