diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-19 15:42:26 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-19 15:42:26 +0000 |
commit | abeedb0875f3fb8e8d1329b8dc885b159cb61841 (patch) | |
tree | 015944ec5e97a34f9f989c320aadfb2a6896d049 | |
parent | b70f99d15f3f139523aa8f1dcb200fa8a8aaa16b (diff) |
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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36989 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | array.c | 3 | ||||
-rw-r--r-- | enum.c | 1 | ||||
-rw-r--r-- | internal.h | 1 | ||||
-rw-r--r-- | test/ruby/test_array.rb | 2 | ||||
-rw-r--r-- | test/ruby/test_enum.rb | 2 | ||||
-rw-r--r-- | vm_eval.c | 22 |
7 files changed, 37 insertions, 3 deletions
@@ -1,3 +1,12 @@ +Thu Sep 20 00:42:20 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * 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@ruby-lang.org> * ext/openssl/ossl_ssl.c (ossl_sslctx_attrs): add npn_select_db to @@ -2795,7 +2795,8 @@ take_items(VALUE obj, long n) 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; } @@ -2010,6 +2010,7 @@ enum_zip(int argc, VALUE *argv, VALUE obj) 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)); } } diff --git a/internal.h b/internal.h index e67273e0e8..3a2331a867 100644 --- a/internal.h +++ b/internal.h @@ -286,6 +286,7 @@ void rb_vm_bugreport(void); /* 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); diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 137c124f60..60b08cd1bc 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1890,7 +1890,7 @@ class TestArray < Test::Unit::TestCase 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 diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb index 1d509b59de..65e9135d69 100644 --- a/test/ruby/test_enum.rb +++ b/test/ruby/test_enum.rb @@ -277,7 +277,7 @@ class TestEnumerable < Test::Unit::TestCase 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 @@ -976,6 +976,28 @@ rb_block_call(VALUE obj, ID mid, int argc, VALUE * argv, 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) { |