From: "KISHIMOTO, Makoto" Date: 2015-01-13T13:48:41+09:00 Subject: [ruby-list:50056] Re: x ||= 1 きしもとです とり急ぎ最初の急所のみ。 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"