ruby-changes:24937
From: nobu <ko1@a...>
Date: Thu, 20 Sep 2012 00:42:39 +0900 (JST)
Subject: [ruby-changes:24937] nobu:r36989 (trunk): array.c, enum.c: TypeError in zip
nobu 2012-09-20 00:42:26 +0900 (Thu, 20 Sep 2012) New Revision: 36989 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36989 Log: array.c, enum.c: TypeError in zip * array.c (take_items), enum.c (enum_zip): raise TypeError at non-enumerable objects, not NoMethodError. [ruby-dev:46145] [Bug #7038] * vm_eval.c (rb_check_block_call): check_funcall variant with block function. Modified files: trunk/ChangeLog trunk/array.c trunk/enum.c trunk/internal.h trunk/test/ruby/test_array.rb trunk/test/ruby/test_enum.rb trunk/vm_eval.c Index: array.c =================================================================== --- array.c (revision 36988) +++ array.c (revision 36989) @@ -2795,7 +2795,8 @@ if (!NIL_P(result)) return rb_ary_subseq(result, 0, n); result = rb_ary_new2(n); args[0] = result; args[1] = (VALUE)n; - rb_block_call(obj, rb_intern("each"), 0, 0, take_i, (VALUE)args); + if (rb_check_block_call(obj, rb_intern("each"), 0, 0, take_i, (VALUE)args) == Qundef) + Check_Type(obj, T_ARRAY); return result; } Index: ChangeLog =================================================================== --- ChangeLog (revision 36988) +++ ChangeLog (revision 36989) @@ -1,3 +1,12 @@ +Thu Sep 20 00:42:20 2012 Nobuyoshi Nakada <nobu@r...> + + * array.c (take_items), enum.c (enum_zip): raise TypeError at + non-enumerable objects, not NoMethodError. [ruby-dev:46145] + [Bug #7038] + + * vm_eval.c (rb_check_block_call): check_funcall variant with block + function. + Tue Sep 18 17:51:29 2012 NARUSE, Yui <naruse@r...> * ext/openssl/ossl_ssl.c (ossl_sslctx_attrs): add npn_select_db to Index: enum.c =================================================================== --- enum.c (revision 36988) +++ enum.c (revision 36989) @@ -2010,6 +2010,7 @@ if (!allary) { CONST_ID(conv, "to_enum"); for (i=0; i<argc; i++) { + if (!rb_respond_to(argv[i], id_each)) Check_Type(argv[i], T_ARRAY); argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each)); } } Index: vm_eval.c =================================================================== --- vm_eval.c (revision 36988) +++ vm_eval.c (revision 36989) @@ -976,7 +976,29 @@ return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); } +static VALUE +iterate_check_method(VALUE obj) +{ + const struct iter_method_arg * arg = + (struct iter_method_arg *) obj; + + return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv); +} + VALUE +rb_check_block_call(VALUE obj, ID mid, int argc, VALUE * argv, + VALUE (*bl_proc) (ANYARGS), VALUE data2) +{ + struct iter_method_arg arg; + + arg.obj = obj; + arg.mid = mid; + arg.argc = argc; + arg.argv = argv; + return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2); +} + +VALUE rb_each(VALUE obj) { return rb_call(obj, idEach, 0, 0, CALL_FCALL); Index: internal.h =================================================================== --- internal.h (revision 36988) +++ internal.h (revision 36989) @@ -286,6 +286,7 @@ /* vm_eval.c */ void Init_vm_eval(void); VALUE rb_current_realfilepath(void); +VALUE rb_check_block_call(VALUE, ID, int, VALUE *, VALUE (*)(ANYARGS), VALUE); /* vm_method.c */ void Init_eval_method(void); Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 36988) +++ test/ruby/test_array.rb (revision 36989) @@ -1890,7 +1890,7 @@ ary = Object.new def ary.to_a; [1, 2]; end - assert_raise(NoMethodError){ %w(a b).zip(ary) } + assert_raise(TypeError, NoMethodError) {%w(a b).zip(ary)} def ary.each; [3, 4].each{|e|yield e}; end assert_equal([['a', 3], ['b', 4]], %w(a b).zip(ary)) def ary.to_ary; [5, 6]; end Index: test/ruby/test_enum.rb =================================================================== --- test/ruby/test_enum.rb (revision 36988) +++ test/ruby/test_enum.rb (revision 36989) @@ -277,7 +277,7 @@ ary = Object.new def ary.to_a; [1, 2]; end - assert_raise(NoMethodError){ %w(a b).zip(ary) } + assert_raise(TypeError, NoMethodError) {%w(a b).zip(ary)} def ary.each; [3, 4].each{|e|yield e}; end assert_equal([[1, 3], [2, 4], [3, nil], [1, nil], [2, nil]], @obj.zip(ary)) def ary.to_ary; [5, 6]; end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/