From 326d26e6e38ef652aa3d03acabc4e7687582370d Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 28 Aug 2019 16:41:39 -0700 Subject: [PATCH] Make Enumerator::Chain#each treat lambdas as lambda Previously, lambdas were converted to procs because of how rb_block_call works. Switch to rb_funcall_with_block, which handles procs as procs and lambdas as lambdas. Fixes [Bug #15613] --- enumerator.c | 9 +-------- test/ruby/test_enumerator.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/enumerator.c b/enumerator.c index 96daad2b4b..b8ce9ad20b 100644 --- a/enumerator.c +++ b/enumerator.c @@ -2859,12 +2859,6 @@ enum_chain_enum_size(VALUE obj, VALUE args, VALUE eobj) return enum_chain_size(obj); } -static VALUE -enum_chain_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(_, block)) -{ - return rb_funcallv(block, id_call, argc, argv); -} - static VALUE enum_chain_enum_no_size(VALUE obj, VALUE args, VALUE eobj) { @@ -2896,10 +2890,9 @@ enum_chain_each(int argc, VALUE *argv, VALUE obj) enums = objptr->enums; block = rb_block_proc(); - for (i = 0; i < RARRAY_LEN(enums); i++) { objptr->pos = i; - rb_block_call(RARRAY_AREF(enums, i), id_each, argc, argv, enum_chain_yield_block, block); + rb_funcall_with_block(RARRAY_AREF(enums, i), id_each, argc, argv, block); } return obj; diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb index 54dfebb814..e5526c50db 100644 --- a/test/ruby/test_enumerator.rb +++ b/test/ruby/test_enumerator.rb @@ -811,4 +811,20 @@ def test_chained_enums e5.inspect ) end + + def test_chain_each_lambda + c = Class.new do + include Enumerable + attr_reader :is_lambda + def each(&block) + return to_enum unless block + @is_lambda = block.lambda? + end + end + e = c.new + e.chain.each{} + assert_equal(false, e.is_lambda) + e.chain.each(&->{}) + assert_equal(true, e.is_lambda) + end end -- 2.22.0