[Bug #20325] `Enumerator.product.size` is 0 if any size is 0

This commit is contained in:
Nobuyoshi Nakada 2024-04-16 16:13:19 +09:00
Родитель 53a8ad151b
Коммит 29110fe18d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 3582D74E1FEE4465
2 изменённых файлов: 17 добавлений и 9 удалений

Просмотреть файл

@ -3536,10 +3536,19 @@ static VALUE
enum_product_total_size(VALUE enums)
{
VALUE total = INT2FIX(1);
VALUE sizes = rb_ary_hidden_new(RARRAY_LEN(enums));
long i;
for (i = 0; i < RARRAY_LEN(enums); i++) {
VALUE size = enum_size(RARRAY_AREF(enums, i));
if (size == INT2FIX(0)) {
rb_ary_resize(sizes, 0);
return size;
}
rb_ary_push(sizes, size);
}
for (i = 0; i < RARRAY_LEN(sizes); i++) {
VALUE size = RARRAY_AREF(sizes, i);
if (NIL_P(size) || (RB_TYPE_P(size, T_FLOAT) && isinf(NUM2DBL(size)))) {
return size;

Просмотреть файл

@ -953,11 +953,7 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal(true, e.is_lambda)
end
def test_product
##
## Enumerator::Product
##
def test_product_new
# 0-dimensional
e = Enumerator::Product.new
assert_instance_of(Enumerator::Product, e)
@ -994,15 +990,16 @@ class TestEnumerator < Test::Unit::TestCase
e.each { |x,| heads << x }
assert_equal [1, 1, 2, 2, 3, 3], heads
# Any enumerable is 0 size
assert_equal(0, Enumerator::Product.new([], 1..).size)
# Reject keyword arguments
assert_raise(ArgumentError) {
Enumerator::Product.new(1..3, foo: 1, bar: 2)
}
end
##
## Enumerator.product
##
def test_s_product
# without a block
e = Enumerator.product(1..3, %w[a b])
assert_instance_of(Enumerator::Product, e)
@ -1029,6 +1026,8 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal(nil, e.size)
assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"]], e.take(4)
assert_equal(0, Enumerator.product([], 1..).size)
# Reject keyword arguments
assert_raise(ArgumentError) {
Enumerator.product(1..3, foo: 1, bar: 2)