Skip to content

Commit c2a159b

Browse files
committed
Fix Enumerator::Lazy#with_index to start with new index for multiple enumerations
1 parent 44a5bf5 commit c2a159b

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
@@ -19,6 +19,7 @@ Bug fixes:
1919
* Fix `Array#pack` with `x*` to not output null characters (#2614, @bjfish).
2020
* Fix `Random#rand` not returning random floats when given float ranges (#2612, @bjfish).
2121
* Fix `Array#sample` for `[]` when called without `n` and a `Random` is given (#2612, @bjfish).
22+
* Fix `Enumerator::Lazy#with_index` to start with new index for multiple enumerations (@bjfish).
2223

2324
Compatibility:
2425

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
@@ -505,16 +508,17 @@ def with_index(offset=0, &block)
505508
offset = if Primitive.nil?(offset)
506509
0
507510
else
508-
Truffle::Type.coerce_to offset, Integer, :to_int
511+
offset
509512
end
510513

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

0 commit comments

Comments
 (0)