さかもとです

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

x += 1 
  => x = x + 1 なので
x ||= 1
  => x = x || 1 と思っていました 。

-----Original Message-----
From: ruby-list [mailto:ruby-list-bounces / ruby-lang.org] On Behalf Of 5.5
Sent: Tuesday, January 13, 2015 12:40 PM
To: ruby-list / ruby-lang.org
Subject: [ruby-list:50053] x ||= 1

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