From: Tanaka Akira Date: 2007-06-23T02:56:34+09:00 Subject: [ruby-dev:31037] Re: Method#to_procと多値 In article <20070619.011013.164845677.masahiro.sakai@gmail.com>, Masahiro Sakai (酒井政裕) writes: > 以下のようなコードを実行したとき、 > コメントの通りの実装ならば 1 が表示されるはずですが、 > 実際には 0 が表示されます。 > > def m(*args) > p args.length > end > method(:m).to_proc.call([]) てきとうにいじってみると、こんな感じでしょうか。 ただ、C レベルにおけるブロック引数渡しについてはまともに検討 されていないので、そこから始めないと、という感じがしますが。 Index: proc.c =================================================================== --- proc.c (リビジョン 12587) +++ proc.c (作業コピー) @@ -1320,6 +1320,12 @@ } static VALUE +mlambda(VALUE method) +{ + return rb_funcall(Qnil, rb_intern("lambda"), 0); +} + +static VALUE bmcall(VALUE args, VALUE method) { volatile VALUE a; @@ -1363,7 +1369,7 @@ * end * end */ - proc = rb_iterate((VALUE (*)(VALUE))mproc, 0, bmcall, method); + proc = rb_iterate((VALUE (*)(VALUE))mlambda, 0, bmcall, method); return proc; } Index: vm.c =================================================================== --- vm.c (リビジョン 12587) +++ vm.c (作業コピー) @@ -665,15 +665,25 @@ NODE *ifunc = (NODE *) block->iseq; VALUE val; VALUE arg; + rb_proc_t *proc = NULL; - if (argc == 1) { - arg = *argv; + if (block->proc) { + GetProcPtr(block->proc, proc); } - else if (argc > 1) { - arg = rb_ary_new4(argc, argv); + + if (proc && proc->is_lambda) { + arg = rb_ary_new4(argc, argv); } else { - arg = rb_ary_new(); + if (argc == 1) { + arg = *argv; + } + else if (argc > 1) { + arg = rb_ary_new4(argc, argv); + } + else { + arg = rb_ary_new(); + } } push_frame(th, 0, FRAME_MAGIC_IFUNC, -- [田中 哲][たなか あきら][Tanaka Akira]