diff options
-rw-r--r-- | enumerator.c | 9 | ||||
-rw-r--r-- | test/ruby/test_enumerator.rb | 17 |
2 files changed, 17 insertions, 9 deletions
diff --git a/enumerator.c b/enumerator.c index 989fdb3426..193a865dbc 100644 --- a/enumerator.c +++ b/enumerator.c @@ -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; diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb index 825c191d87..7599d43463 100644 --- a/test/ruby/test_enumerator.rb +++ b/test/ruby/test_enumerator.rb @@ -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) |