[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
parent 53a8ad151b
commit 29110fe18d
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
2 changed files with 17 additions and 9 deletions

View File

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

View File

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