From: Daisuke Yokotsuka Date: 2015-01-17T11:34:04+09:00 Subject: [ruby-list:50064] Re: x ||= 1 横塚と申します。 これまでの一連の議論、興味深く拝見してます。 私もコンパイラ開発に携わっていたもので、「うん、うん、なるほど」と 思いながら読んでおり、実装上の都合も十分理解しているのですが・・・ ユーザの立場で言うと、未定義のまま参照されたらデフォルト値を返すよりも 素直に「未定義」エラーになってくれた方が嬉しいような気がしてきました。 数十行の使い捨てスクリプトを書くのなら良いのですが、数Ks以上のプログラムを まじめに作ろうと思うと、それなりの作法が必要と思います。 作法には、変数には最初の参照前に初期値を代入するということも含みます。 自分でのデバッグや、ましてや数年後に他人が自分の書いたスクリプトを エンハンスすることを想定すると、グローバル変数やインスタンス変数でも 定数と同じ挙動をしてくれるのが一番嬉しいかな。 実際にも、インスタンス変数をタイプミスしているのに、コンパイル時には エラーとならず、実行時に変な動作をするので、やっと気付くということが まま有ります。 私の感覚がおかしいのかな。 皆様、如何でしょう。 <20150117110728.EFC3.BF847F80@nifty.com> の、 "[ruby-list:50063] Re: x ||= 1" において、 "take_tk "さんは書きました: > たけ(tk)です > > 言葉足らずにすみませんでした。 > > > 式1 が未定義もしくは偽のとき 式1 に 式2 の評価結果を代入し > >  その値を全体の評価値とする。 > >  式1 が真のとき,その評価結果を全体の評価値とする。 > > 自己代入演算子は 式1 が未定義かどうかで区別しないということです。 > > > 式1 が偽のとき 式1 に 式2 の評価結果を代入し > >  その値を全体の評価値とする。 > >  式1 が真のとき,その評価結果を全体の評価値とする。 > >  式1 が未定義の変数や定数、ハッシュなど場合には・・・と続く・・・ > > という感じでしょう。 > > --- > > ローカル変数でエラーにならない理由と > グローバル変数やインスタンス変数やハッシュでエラーにならない理由とは違い > ます。 > > グローバル変数やインスタンス変数やハッシュでエラーにならない理由は、それ > らが未定義のまま参照されてもデフォルト値 nil を返すからです。 > > irb(main):008:0> defined? @x #=> nil ・・未定義でも > irb(main):009:0> @x #=> nil ・・デフォルト値で評価される。 > irb(main):010:0> @x &&= 1 #=> nil ・・デフォルト値で評価している。 > irb(main):011:0> @x #=> nil > irb(main):012:0> defined? @x #=> nil ・・未定義のまま > > irb(main):023:0> h = {} #=> {} > irb(main):024:0> h #=> {} ・・h[:x]が未定義でも > irb(main):025:0> h[:x] #=> nil ・・デフォルト値で評価される。 > irb(main):026:0> h[:x] &&= 1 #=> nil ・・デフォルト値で評価している。 > irb(main):027:0> h[:x] #=> nil > irb(main):028:0> h #=> {} ・・h[:x]は未定義のまま > > それに対して、 > ローカル変数でエラーにならない理由は、ローカル変数が代入演算子の左辺に来 > たときには nil で初期化されるからです。 > > irb(main):002:0> defined? x #=> nil > irb(main):003:0> x # NameError: undefined local variable or method > irb(main):005:0> x &&= 1 #=> nil ・・代入演算子の左辺に来たので > irb(main):006:0> x #=> nil ・・nil で初期化されている。 > irb(main):007:0> defined? x #=> "local-variable" > > 定数でエラーになるのは、nil で初期化されることもなく、デフォルト値も返さ > ないので、参照の段階でエラーになるからです。 > > irb(main):013:0> defined? X #=> nil > irb(main):014:0> X # NameError: uninitialized constant X > irb(main):015:0> X &&= 1 # NameError: uninitialized constant X > irb(main):016:0> X # NameError: uninitialized constant X > irb(main):017:0> defined? X #=> nil > > -- Daisuke Yokotsuka yokots_d@c3-net.ne.jp