From: nobu.nakada@... Date: 2003-03-07T09:01:43+09:00 Subject: [ruby-dev:19752] Re: (1.8.0-preview2) Proc#call なかだです。 At Fri, 7 Mar 2003 03:18:10 +0900, Fukumoto Atsushi wrote: > irb(main):001:0> f1 = lambda { |r,| p r } > => # > irb(main):002:0> a0 = [] > => [] > irb(main):003:0> f1.call([], *a0) > ArgumentError: wrong number of arguments (0 for 2) > from (irb):3 > from (irb):1:in `call' > from (irb):3 > > これは仕様でしょうか? 1.6.8 ではエラーにならず、 [] が引数として渡さ > れました。 少なくとも(0 for 2)というのは正しくないはずですが、これはエラー になるべきなんでしょうか。なんとなく[]を期待しそうな気が。 > irb(main):005:0> f2 = lambda { |r,*l| p r,l } > => # > irb(main):006:0> a1 = [1] > => [1] > irb(main):007:0> f2.call([], *a1) > [] > [1] > => nil > irb(main):008:0> f2.call([[], *a1]) > [] > [1704055] > => nil > > 最後のは何か変なところをアクセスしているようです。プラットフォームによっ > てはSEGVになります。 こっちはまぁ単純なバグですね。 Index: eval.c =================================================================== RCS file: //sharui/cvs/ruby/src/ruby/eval.c,v retrieving revision 1.405 diff -u -2 -p -r1.405 eval.c --- eval.c 27 Feb 2003 08:04:32 -0000 1.405 +++ eval.c 6 Mar 2003 23:42:22 -0000 @@ -4025,15 +4025,17 @@ massign(self, node, val, pcall) { NODE *list; + VALUE tmp; long i = 0, len; len = RARRAY(val)->len; list = node->nd_head; - if (len == 1 && list) { + if (len == 1 && list && (list->nd_next || node->nd_args)) { VALUE v = RARRAY(val)->ptr[0]; - VALUE tmp = rb_check_array_type(v); + tmp = rb_check_array_type(v); if (NIL_P(tmp)) { assign(self, list->nd_head, v, pcall); list = list->nd_next; + i = 1; } else { @@ -4044,5 +4046,4 @@ massign(self, node, val, pcall) } } - i = 1; } else { @@ -4051,4 +4052,5 @@ massign(self, node, val, pcall) list = list->nd_next; } + tmp = val; } if (pcall && list) goto arg_error; @@ -4058,5 +4060,5 @@ massign(self, node, val, pcall) } else if (!list && ind_args, rb_ary_new4(len-i, RARRAY(val)->ptr+i), pcall); + assign(self, node->nd_args, rb_ary_new4(len-i, RARRAY(tmp)->ptr+i), pcall); } else { @@ -4489,11 +4491,16 @@ rb_f_missing(argc, argv, obj) char buf[BUFSIZ]; int noclass = (!d || desc[0]=='#'); + int n = 0; + VALUE args[3]; snprintf(buf, BUFSIZ, format, rb_id2name(id), desc, noclass ? "" : ":", noclass ? "" : rb_obj_classname(obj)); - exc = rb_exc_new2(exc, buf); - rb_iv_set(exc, "name", argv[0]); - rb_iv_set(exc, "args", rb_ary_new4(argc-1, argv+1)); + args[n++] = rb_str_new2(buf); + args[n++] = argv[0]; + if (exc == rb_eNoMethodError) { + args[n++] = rb_ary_new4(argc-1, argv+1); + } + exc = rb_class_new_instance(n, args, exc); rb_exc_raise(exc); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦