なかだです。

At Fri, 7 Mar 2003 03:18:10 +0900,
Fukumoto Atsushi wrote:
> irb(main):001:0> f1 = lambda { |r,| p r }
> => #<Proc:0x001a5180@(irb):1>
> 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 }
> => #<Proc:0x00197594@(irb):5>
> 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 && i<len) { - assign(self, node->nd_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はできる。 中田 伸悦