[ruby-core:121076] [Ruby master Bug#21142] Lazy enumerator `.each_with_index` ignores `.take(0)` before it

Issue #21142 has been reported by aaronkison (Aaron Kison). ---------------------------------------- Bug #21142: Lazy enumerator `.each_with_index` ignores `.take(0)` before it https://bugs.ruby-lang.org/issues/21142 * Author: aaronkison (Aaron Kison) * Status: Open * ruby -v: 3.2.7 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Minimum code to produce problem: ``` class Numbers; def each; 100.times { yield _1 }; end; include Enumerable; end Numbers.new.lazy.take(0).each_with_index.map { _1 }.to_a ``` Output (at ruby 3.2.7, and 3.3.0): ``` [0, 1, ..., 99] ``` Expected output (and was as at ruby 3.1.4): ``` [] ``` It works when it opposite ordering: `Numbers.new.lazy.each_with_index.take(0).map { _1 }.to_a`. I suspect it may be related to the change here https://github.com/ruby/ruby/pull/11868/files but I'm not familiar with any of that code. It seems like it replaces an allocated index with a counting index, which my hunch is it works for every value except for 0. -- https://bugs.ruby-lang.org/

Issue #21142 has been updated by mame (Yusuke Endoh). Assignee set to alanwu (Alan Wu) @alanwu What do you think? cc/ @knu ---------------------------------------- Bug #21142: Lazy enumerator `.each_with_index` ignores `.take(0)` before it https://bugs.ruby-lang.org/issues/21142#change-112250 * Author: aaronkison (Aaron Kison) * Status: Open * Assignee: alanwu (Alan Wu) * ruby -v: 3.2.7 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Minimum code to produce problem: ``` class Numbers; def each; 100.times { yield _1 }; end; include Enumerable; end Numbers.new.lazy.take(0).each_with_index.map { _1 }.to_a ``` Output (at ruby 3.2.7, and 3.3.0): ``` [0, 1, ..., 99] ``` Expected output (and was as at ruby 3.1.4): ``` [] ``` It works when it opposite ordering: `Numbers.new.lazy.each_with_index.take(0).map { _1 }.to_a`. I suspect it may be related to the change here https://github.com/ruby/ruby/pull/11868/files but I'm not familiar with any of that code. It seems like it replaces an allocated index with a counting index, which my hunch is it works for every value except for 0. -- https://bugs.ruby-lang.org/

Issue #21142 has been updated by alanwu (Alan Wu). Assignee deleted (alanwu (Alan Wu)) The pull request you point was released with 3.4, but the problem started with 3.2, so it's not due to the change in the pull request. ---------------------------------------- Bug #21142: Lazy enumerator `.each_with_index` ignores `.take(0)` before it https://bugs.ruby-lang.org/issues/21142#change-112258 * Author: aaronkison (Aaron Kison) * Status: Open * ruby -v: 3.2.7 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Minimum code to produce problem: ``` class Numbers; def each; 100.times { yield _1 }; end; include Enumerable; end Numbers.new.lazy.take(0).each_with_index.map { _1 }.to_a ``` Output (at ruby 3.2.7, and 3.3.0): ``` [0, 1, ..., 99] ``` Expected output (and was as at ruby 3.1.4): ``` [] ``` It works when it opposite ordering: `Numbers.new.lazy.each_with_index.take(0).map { _1 }.to_a`. I suspect it may be related to the change here https://github.com/ruby/ruby/pull/11868/files but I'm not familiar with any of that code. It seems like it replaces an allocated index with a counting index, which my hunch is it works for every value except for 0. -- https://bugs.ruby-lang.org/

Issue #21142 has been updated by Hanmac (Hans Mackowiak). You might want a different function. `Enumerable#each_with_index` does reset the Enumerator, while `Enumerator#with_index` does not. ```ruby p 3.times.lazy.take(0).each_with_index.to_a #[[0, 0], [1, 1], [2, 2]] p 3.times.lazy.take(0).with_index.to_a #[] ``` ---------------------------------------- Bug #21142: Lazy enumerator `.each_with_index` ignores `.take(0)` before it https://bugs.ruby-lang.org/issues/21142#change-112259 * Author: aaronkison (Aaron Kison) * Status: Open * ruby -v: 3.2.7 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Minimum code to produce problem: ``` class Numbers; def each; 100.times { yield _1 }; end; include Enumerable; end Numbers.new.lazy.take(0).each_with_index.map { _1 }.to_a ``` Output (at ruby 3.2.7, and 3.3.0): ``` [0, 1, ..., 99] ``` Expected output (and was as at ruby 3.1.4): ``` [] ``` It works when it opposite ordering: `Numbers.new.lazy.each_with_index.take(0).map { _1 }.to_a`. I suspect it may be related to the change here https://github.com/ruby/ruby/pull/11868/files but I'm not familiar with any of that code. It seems like it replaces an allocated index with a counting index, which my hunch is it works for every value except for 0. -- https://bugs.ruby-lang.org/

Issue #21142 has been updated by Hanmac (Hans Mackowiak). @nobu your opinion on this `take(0)` thing? ---------------------------------------- Bug #21142: Lazy enumerator `.each_with_index` ignores `.take(0)` before it https://bugs.ruby-lang.org/issues/21142#change-112332 * Author: aaronkison (Aaron Kison) * Status: Open * ruby -v: 3.2.7 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Minimum code to produce problem: ``` class Numbers; def each; 100.times { yield _1 }; end; include Enumerable; end Numbers.new.lazy.take(0).each_with_index.map { _1 }.to_a ``` Output (at ruby 3.2.7, and 3.3.0): ``` [0, 1, ..., 99] ``` Expected output (and was as at ruby 3.1.4): ``` [] ``` It works when it opposite ordering: `Numbers.new.lazy.each_with_index.take(0).map { _1 }.to_a`. I suspect it may be related to the change here https://github.com/ruby/ruby/pull/11868/files but I'm not familiar with any of that code. It seems like it replaces an allocated index with a counting index, which my hunch is it works for every value except for 0. -- https://bugs.ruby-lang.org/
participants (4)
-
aaronkison (Aaron Kison)
-
alanwu (Alan Wu)
-
Hanmac (Hans Mackowiak)
-
mame (Yusuke Endoh)