defined?
の中で代入をすると、バイトコードには変数定義が現れないけれど、変数が定義されると知った。
$ ruby --dump=insns -e 'defined? a=1; p a' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,17)> (catch: false) local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] a@0 0000 putself ( 1)[Li] 0001 getlocal_WC_0 a@0 0003 opt_send_without_block <calldata!mid:p, argc:1, FCALL|ARGS_SIMPLE> 0005 leave # 変数定義はしっかりある $ ruby -e 'defined? a=1; p a; p binding.local_variables' nil [:a]
ruby-jpで「特定のローカル変数への代入がバイトコード上にあらわれないもの」は何があるか、という質問がしばらく前にあったので、それを思い出して挙動を眺めていた。
↑を思い出したきっかけが、コードを読んでいてdefined? yield
があり、「yieldという名前のメソッドが定義されているかどうかをdefined?
で検査できないのでは…?」と思いついたからだった。
これをきっかけにdefined?
のドキュメントを読んでいて、ローカル変数のことに思い至った。