帥

羃√臼磴蠅とうございます。
勉強になります。
今後ともよろしくお願いします。

中井



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規格の
>> どこに書いてあるのか・未定義なのか・はたまた規格違反な振る舞いのか、
>> あたりは、自分には判断が付きませんでした。
>>
>> もし詳しい方が答えてくだされば、自分としてはうれしいです。
>> --
>> 斎藤 匡