1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2012-09-19 15:42:26 +00:00
parent b70f99d15f
commit abeedb0875
7 changed files with 37 additions and 3 deletions

View file

@ -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

View file

@ -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;
}

1
enum.c
View file

@ -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));
}
}

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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)
{