Skip to content

Commit 947cbab

Browse files
committed
[GR-37235] Fix Enumerator::Lazy#with_index to start with new index for multiple enumerations
PullRequest: truffleruby/3230
2 parents c800fea + c2a159b commit 947cbab

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Bug fixes:
3939
* Fix `Array#sample` for `[]` when called without `n` and a `Random` is given (#2612, @bjfish).
4040
* Fix `Module#const_get` to raise a `NameError` when nested modules do not exist (#2610, @bjfish).
4141
* Ensure native `VALUE`s returned from C are unwrapped before the objects can be collected (@aardvark179).
42+
* Fix `Enumerator::Lazy#with_index` to start with new index for multiple enumerations (@bjfish).
4243

4344
Compatibility:
4445

spec/ruby/core/enumerator/lazy/with_index_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,13 @@
2626
(0..Float::INFINITY).lazy.with_index { |i, idx| result << [i * 2, idx] }.first(3)
2727
result.should == [[0,0],[2,1],[4,2]]
2828
end
29+
30+
it "resets after a new call to each" do
31+
enum = (0..2).lazy.with_index.map { |i, idx| [i, idx] }
32+
result = []
33+
enum.each { |i, idx| result << [i, idx] }
34+
enum.each { |i, idx| result << [i, idx] }
35+
result.should == [[0,0], [1,1], [2,2], [0,0], [1,1], [2,2]]
36+
end
2937
end
3038
end

src/main/ruby/truffleruby/core/enumerator.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,13 @@ def self.produce(initial = nil)
230230
end
231231

232232
class Yielder
233+
attr_accessor :memo
234+
233235
def initialize(&block)
234236
raise LocalJumpError, 'Expected a block to be given' unless block_given?
235237

236238
@proc = block
239+
@memo = nil
237240

238241
self
239242
end
@@ -507,16 +510,17 @@ def with_index(offset=0, &block)
507510
offset = if Primitive.nil?(offset)
508511
0
509512
else
510-
Truffle::Type.coerce_to offset, Integer, :to_int
513+
offset
511514
end
512515

513516
Lazy.new(self, enumerator_size) do |yielder, *args|
517+
memo = yielder.memo || offset
514518
if block
515-
yielder.yield yield(*args, offset)
519+
yielder.yield yield(*args, memo)
516520
else
517-
yielder.yield(*args, offset)
521+
yielder.yield(*args, memo)
518522
end
519-
offset += 1
523+
yielder.memo = Primitive.rb_num2long(memo) + 1
520524
end
521525
end
522526

0 commit comments

Comments
 (0)