mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix calling enumerator methods such as with_index on Enumerator::Chain
This previously raised a TypeError. Wrap the Enumerator::Chain in an Enumerator to work around the problem. Fixes [Bug #17216]
This commit is contained in:
parent
13dc005347
commit
bf40fe9fed
Notes:
git
2021-03-07 06:56:44 +09:00
2 changed files with 18 additions and 16 deletions
30
enumerator.c
30
enumerator.c
|
@ -517,27 +517,25 @@ static VALUE
|
|||
lazy_to_enum_i(VALUE self, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat);
|
||||
|
||||
VALUE
|
||||
rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
|
||||
rb_enumeratorize_with_size_kw(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
|
||||
{
|
||||
/* Similar effect as calling obj.to_enum, i.e. dispatching to either
|
||||
Kernel#to_enum vs Lazy#to_enum */
|
||||
if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
|
||||
return lazy_to_enum_i(obj, meth, argc, argv, size_fn, rb_keyword_given_p());
|
||||
else
|
||||
return enumerator_init(enumerator_allocate(rb_cEnumerator),
|
||||
obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p());
|
||||
VALUE base_class = rb_cEnumerator;
|
||||
|
||||
if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy))) {
|
||||
base_class = rb_cLazy;
|
||||
}
|
||||
else if (RTEST(rb_obj_is_kind_of(obj, rb_cEnumChain))) {
|
||||
obj = enumerator_init(enumerator_allocate(rb_cEnumerator), obj, sym_each, 0, 0, 0, Qnil, false);
|
||||
}
|
||||
|
||||
return enumerator_init(enumerator_allocate(base_class),
|
||||
obj, meth, argc, argv, size_fn, Qnil, kw_splat);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_enumeratorize_with_size_kw(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
|
||||
rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
|
||||
{
|
||||
/* Similar effect as calling obj.to_enum, i.e. dispatching to either
|
||||
Kernel#to_enum vs Lazy#to_enum */
|
||||
if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
|
||||
return lazy_to_enum_i(obj, meth, argc, argv, size_fn, kw_splat);
|
||||
else
|
||||
return enumerator_init(enumerator_allocate(rb_cEnumerator),
|
||||
obj, meth, argc, argv, size_fn, Qnil, kw_splat);
|
||||
return rb_enumeratorize_with_size_kw(obj, meth, argc, argv, size_fn, rb_keyword_given_p());
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
|
@ -816,6 +816,10 @@ class TestEnumerator < Test::Unit::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_chain_with_index
|
||||
assert_equal([[3, 0], [4, 1]], [3].chain([4]).with_index.to_a)
|
||||
end
|
||||
|
||||
def test_produce
|
||||
assert_raise(ArgumentError) { Enumerator.produce }
|
||||
|
||||
|
|
Loading…
Reference in a new issue