[ruby-core:109638] [Ruby master Bug#18971] Enumerator::Lazy.take(0) leaks first element into next operation
From:
"jeremyevans0 (Jeremy Evans)" <noreply@...>
Date:
2022-08-23 05:58:39 UTC
List:
ruby-core #109638
Issue #18971 has been updated by jeremyevans0 (Jeremy Evans).
Are you sure this has been fixed? I tried with Ruby 2.7-3.1 and current master and did not get all `[]` results on any Ruby version I tested.
There is specific code to deal with an argument of 0, though I don't understand what it does. It comes from commit 29f73009ca934cfa7b51d1de4d22933ab56dc602 .
One way I found to work around this is to use an intermediate `cycle(0)` enumerator. I submitted a pull request for that (https://github.com/ruby/ruby/pull/6273), though I expect @nobu could come up with a more elegant solution.
----------------------------------------
Bug #18971: Enumerator::Lazy.take(0) leaks first element into next operation
https://bugs.ruby-lang.org/issues/18971#change-98857
* Author: Voileexperiments (Library Voile)
* Status: Open
* Priority: Normal
* ruby -v: 3.0.0p0 (2020-12-25 revision 95aff21468)
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
These results with lazy enumerators are as expected:
``` ruby
(2..10).take(0).to_a # => []
(2..10).take(0).map(:&itself).to_a # => []
(2..10).lazy.take(0).to_a # => []
```
However, once another operation is added after `take(0)`, if first element will pass through directly it will leak through:
``` ruby
(2..10).lazy.take(0).map(&:itself).to_a # => [2]
(2..10).lazy.take(0).select(&:even?).to_a # => [2]
(2..10).lazy.take(0).select(&:odd?).to_a # => []
(2..10).lazy.take(0).reject(&:even?).to_a # => []
(2..10).lazy.take(0).reject(&:odd?).to_a # => [2]
(2..10).lazy.take(0).take(1).to_a # => [2]
(2..10).lazy.take(0).take(0).take(1).to_a # => [2]
(2..10).lazy.take(0).drop(0).to_a => [2]
(2..10).lazy.take(0).find_all {|_| true}.to_a # => [2]
(2..10).lazy.take(0).zip((12..20)).to_a => [[2, 12]]
(2..10).lazy.take(0).uniq.to_a # => [2]
(2..10).lazy.take(0).sort.to_a # => []
(2..2).lazy.take(0).sort.to_a # => []
```
Non lazy versions all return `[]` as expected.
In 3.1.0 All of them behave as expected as well:
``` ruby
(2..10).lazy.take(0).map(&:itself).to_a # => []
(2..10).lazy.take(0).select(&:even?).to_a.to_a # => []
(2..10).lazy.take(0).select(&:odd?).to_a.to_a # => []
(2..10).lazy.take(0).reject(&:even?).to_a.to_a # => []
(2..10).lazy.take(0).reject(&:odd?).to_a.to_a # => []
(2..10).lazy.take(0).take(1).to_a # => []
(2..10).lazy.take(0).take(0).take(1).to_a # => []
(2..10).lazy.take(0).drop(0).to_a => []
(2..10).lazy.take(0).find_all {|_| true}.to_a # => []
(2..10).lazy.take(0).zip((12..20)).to_a => []
(2..10).lazy.take(0).uniq.to_a # => []
(2..10).lazy.take(0).sort.to_a # => []
(2..2).lazy.take(0).sort.to_a # => []
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>