[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]