[ruby-list:50584] Re: [質問] 変数pが定義されている時のabsの動作について
From:
Katsunori Nakai <bigswim.atom@...>
Date:
2017-09-06 02:45:14 UTC
List:
ruby-list #50584
みなさま 沢山のご回答、ありがとうございます。 勉強になります。 今後ともよろしくお願いします。 中井 2017年9月6日 8:06 dogatana <dogatana@gmail.com>: > こんにちは。 > > rubyがどのように解釈しているかはrubyに聞くのが一番ということで、 > 次のコードを考えてみました。 > > ~~~ > iseq = RubyVM::InstructionSequence.compile(<<END) > p (-1).abs > p = 10 > p (-1).abs > END > puts iseq.disasm > ~~~ > > 結果は > > ~~~ > == disasm: #<ISeq:<compiled>@<compiled>>================================ > local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, > kw: -1@-1, kwrest: -1]) > [ 2] p > > # p (-1).abs > > 0000 trace 1 ( 1) > 0002 putself > 0003 putobject -1 > 0005 opt_send_without_block <callinfo!mid:abs, argc:0, ARGS_SIMPLE>, <callcache> > 0008 opt_send_without_block <callinfo!mid:p, argc:1, > FCALL|ARGS_SIMPLE>, <callcache> > 0011 pop > > # p = 10 > 0012 trace 1 ( 2) > 0014 putobject 10 > 0016 setlocal_OP__WC__0 2 > > # p (-1).abs > 0018 trace 1 ( 3) > 0020 putself > 0021 putobject -1 > 0023 opt_send_without_block <callinfo!mid:p, argc:1, > FCALL|ARGS_SIMPLE>, <callcache> > 0026 opt_send_without_block <callinfo!mid:abs, argc:0, ARGS_SIMPLE>, <callcache> > 0029 leave > ~~~ > > putobject -1 の行次にある abs, p (いずれも opt_send_without_block で始まる行) > の順序を見ると、 > > * 最初の実行では ー1 に abs が適用され、次に p が適用されている > * 2回目の実行では -1 に p が適用され、次に abs が適用されている > > となっていますので、これが表示に違いとして出てくるのではないでしょうか。 > > なお、確かに動作が変わるのですが、私見では > > * 同一スコープに同じ名前のメソッドとローカル変数がある > * メソッド(p) の呼び出しで、括弧を省略している > > 場合の動作なので、文法というレベルではなく実装依存のレベルのように思います。 > 適用順を明示的に指定するのであれば、括弧をつければ良いだけですし、同一スコープで > 同じ名前を使用するのは勧められない記述だと思うので。 > > > 市田 > > 2017年9月5日 21:55 Tadashi Saito <tad.a.digger@gmail.com>: >> 斎藤と申します。おもしろい問題ですね。 >> >> 個人的にはなんとなく既視感があるのですが、過去のメール・チケットの >> 中からは、自分はうまく見つけられませんでした。 >> >> Konishiさんが先に投稿されたことで大方カバーされていると思いますが、 >> 自分が調べた点を一つ。 >> >>> ちなみに、ruby 2.4.1p111での動作です。 >> >> >> 手元で試した限り、同名の変数の有無によって振る舞いが変わるのは、 >> 1.8.7〜2.4の全ての系列で同じでした。もっと古いRubyについては、 >> まだ試していません。 >> >> ruby 1.8.7 (2012-06-29 patchlevel 370) [x86_64-linux] >> ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-linux] >> ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] >> ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux] >> ruby 2.2.7p470 (2017-03-28 revision 58194) [x86_64-linux] >> ruby 2.3.4p301 (2017-03-30 revision 58214) [x86_64-linux] >> ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux] >> >> (ちなみに、pが引数をそのまま返り値として返すようになるのは1.9から >> で、1.8.7までは nil が返ります。そのため、1.8.7の実行では (p(-1.3)).abs >> に 対しては nil.abs が実行され、その結果エラーになりました。) >> >> 以上のように、伝統的な振る舞いである(うっかり変えると悲劇が起きそうな) >> のは分かったのですが、これがバグなのか・そうでないのか、JIS/ISO規格の >> どこに書いてあるのか・未定義なのか・はたまた規格違反な振る舞いのか、 >> あたりは、自分には判断が付きませんでした。 >> >> もし詳しい方が答えてくだされば、自分としてはうれしいです。 >> -- >> 斎藤 匡