From 308ccbaeb2c1c0e78d59c0411ddbeede8d2324f0 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Wed, 21 Dec 2022 18:19:19 +0900 Subject: Make product consistently yield an array of N elements instead of N arguments Inconsistency pointed out by @mame: ``` >> Enumerator.product([1], [2], [3]).to_a => [[1, 2, 3]] >> Enumerator.product([1], [2]).to_a => [[1, 2]] >> Enumerator.product([1]).to_a => [1] >> Enumerator.product().to_a => [nil] ``` Got fixed as follows: ``` >> Enumerator.product([1], [2], [3]).to_a => [[1, 2, 3]] >> Enumerator.product([1], [2]).to_a => [[1, 2]] >> Enumerator.product([1]).to_a => [[1]] >> Enumerator.product().to_a => [[]] ``` This was due to the nature of the N-argument funcall in Ruby. --- enumerator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'enumerator.c') diff --git a/enumerator.c b/enumerator.c index 4e0b700f1d..eb402804eb 100644 --- a/enumerator.c +++ b/enumerator.c @@ -3434,7 +3434,7 @@ enumerator_plus(VALUE obj, VALUE eobj) * * The method used against each enumerable object is `each_entry` * instead of `each` so that the product of N enumerable objects - * yields exactly N arguments in each iteration. + * yields an array of exactly N elements in each iteration. * * When no enumerator is given, it calls a given block once yielding * an empty argument list. @@ -3627,7 +3627,7 @@ product_each(VALUE obj, struct product_state *pstate) rb_block_call(eobj, id_each_entry, 0, NULL, product_each_i, (VALUE)pstate); } else { - rb_funcallv(pstate->block, id_call, pstate->argc, pstate->argv); + rb_funcall(pstate->block, id_call, 1, rb_ary_new_from_values(pstate->argc, pstate->argv)); } return obj; -- cgit v1.2.1