[ruby-list:50067] Re: x ||= 1
From:
"5.5" <5.5@...>
Date:
2015-01-17 13:16:43 UTC
List:
ruby-list #50067
5.5 です。 On 15/01/17 11:07, take_tk wrote: > たけ(tk)です > > 言葉足らずにすみませんでした。 > >> 式1 が未定義もしくは偽のとき 式1 に 式2 の評価結果を代入し >> その値を全体の評価値とする。 >> 式1 が真のとき,その評価結果を全体の評価値とする。 > > 自己代入演算子は 式1 が未定義かどうかで区別しないということです。 > >> 式1 が偽のとき 式1 に 式2 の評価結果を代入し >> その値を全体の評価値とする。 >> 式1 が真のとき,その評価結果を全体の評価値とする。 >> 式1 が未定義の変数や定数、ハッシュなど場合には・・・と続く・・・ > > という感じでしょう。 そうですね,真偽と未定義は分けて考えないといけないということ ですね。 > ローカル変数でエラーにならない理由と > グローバル変数やインスタンス変数やハッシュでエラーにならない理由とは違い > ます。 > > グローバル変数やインスタンス変数やハッシュでエラーにならない理由は、それ > らが未定義のまま参照されてもデフォルト値 nil を返すからです。 > それに対して、 > ローカル変数でエラーにならない理由は、ローカル変数が代入演算子の左辺に来 > たときには nil で初期化されるからです。 そうですね。 > 定数でエラーになるのは、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 んー,でもまだちょっと分からない点があります。 X &&= 1 は NameError になるのに,X ||= 1 はならないことです。 それぞれの構文木は s(:op_asgn_and, s(:const, :X), s(:cdecl, :X, s(:lit, 1))) s(:op_asgn_or, s(:const, :X), s(:cdecl, :X, s(:lit, 1))) で,違っているのは :op_asgn_and か :op_asgn_or かだけです。 どちらの場合も,実行の段にはまず s(:const, :X) の部分,つまり 定数 X の参照を行うのだと思うんですが,何が違うんでしょうね。 ※ちなみに Ruby 1.8.7 ではどちらも NameError になりました。 Ruby 1.9 で何かが変わったんですね。 -- 5.5@moji.gr.jp