summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--array.c3
-rw-r--r--enum.c1
-rw-r--r--internal.h1
-rw-r--r--test/ruby/test_array.rb2
-rw-r--r--test/ruby/test_enum.rb2
-rw-r--r--vm_eval.c22
7 files changed, 37 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 7f4112763f..3ff46b2b8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/array.c b/array.c
index 8b2c4c5c8b..0e4061931f 100644
--- a/array.c
+++ b/array.c
@@ -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;
}
diff --git a/enum.c b/enum.c
index ac86c9d550..0e4cf33d12 100644
--- a/enum.c
+++ b/enum.c
@@ -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
diff --git a/vm_eval.c b/vm_eval.c
index 897b0b0659..ef588dd1f6 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -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)
{