From 47db835e58de4a4fbdc89e79ee07247709096cbe Mon Sep 17 00:00:00 2001 From: Lillian Zhang Date: Wed, 11 Nov 2020 17:51:01 -0500 Subject: [PATCH] Implement and untag Enumerator#produce --- CHANGELOG.md | 1 + spec/tags/core/enumerator/produce_tags.txt | 4 ---- src/main/ruby/truffleruby/core/enumerator.rb | 13 +++++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) delete mode 100644 spec/tags/core/enumerator/produce_tags.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index d822a6743ca1..7a45fe8d1b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Compatibility: * Implement `Enumerable#tally` and `Enumerable#filter_map` (#2144 and #2152, @LillianZ). * Implement `Range#minmax`. * Pass more `Enumerator::Lazy#uniq` and `Enumerator::Lazy#chunk` specs (#2146, @LillianZ). +* Implement `Enumerator#produce` (#2160, @zverok) Performance: diff --git a/spec/tags/core/enumerator/produce_tags.txt b/spec/tags/core/enumerator/produce_tags.txt deleted file mode 100644 index a4382b33ed24..000000000000 --- a/spec/tags/core/enumerator/produce_tags.txt +++ /dev/null @@ -1,4 +0,0 @@ -fails:Enumerator.produce creates an infinite enumerator -fails:Enumerator.produce terminates iteration when block raises StopIteration exception -fails:Enumerator.produce when initial value skipped uses nil instead -fails:Enumerator.produce when initial value skipped starts enumerable from result of first block call diff --git a/src/main/ruby/truffleruby/core/enumerator.rb b/src/main/ruby/truffleruby/core/enumerator.rb index 46d3b78722b8..9d4c8ed430de 100644 --- a/src/main/ruby/truffleruby/core/enumerator.rb +++ b/src/main/ruby/truffleruby/core/enumerator.rb @@ -216,6 +216,19 @@ def +(other) Enumerator::Chain.new(self, other) end + def self.produce(initial = nil) + # Taken from https://github.com/zverok/enumerator_generate + raise ArgumentError, 'No block given' unless block_given? + Enumerator.new(Float::INFINITY) do |y| + val = initial == nil ? yield() : initial + + loop do + y << val + val = yield(val) + end + end + end + class Yielder def initialize(&block) raise LocalJumpError, 'Expected a block to be given' unless block_given?