From: "afurm (Andrii Furmanets) via ruby-core" Date: 2026-09-26T13:35:29+00:00 Subject: [ruby-core:126864] [Ruby Bug#22385] Enumerator::Lazy#zip loses to_ary conversions when mixed with enumerable arguments Issue #22385 has been reported by afurm (Andrii Furmanets). ---------------------------------------- Bug #22385: Enumerator::Lazy#zip loses to_ary conversions when mixed with enumerable arguments https://bugs.ruby-lang.org/issues/22385 * Author: afurm (Andrii Furmanets) * Status: Open * ruby -v: ruby 4.1.0dev (2026-09-26T04:24:02Z af/ruby-correctnes.. da3e1fcb68) +PRISM [arm64-darwin27] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- `Enumerator::Lazy#zip` discards a successful `to_ary` conversion when a later argument requires Enumerable iteration. The equivalent eager `Enumerable#zip` call preserves the conversion. ## Reproduction ```ruby array_like = Object.new def array_like.to_ary [:a, :b] end p (1..3).zip(array_like, 10..12) # => [[1, :a, 10], [2, :b, 11], [3, nil, 12]] p (1..3).lazy.zip(array_like).force # => [[1, :a], [2, :b], [3, nil]] p (1..3).lazy.zip(array_like, 10..12).force # => NoMethodError: undefined method 'each' for an Object ``` ## Expected behavior The last expression should return `[[1, :a, 10], [2, :b, 11], [3, nil, 12]]`, matching the eager call. Adding the range should not discard the earlier successful array conversion. If the argument defines both `to_ary` and `each` with different values, the same defect silently uses the `each` values instead of the converted array. ## Affected versions Reproduced on unchanged Ruby master at `da3e1fcb685864a2f58f113e82d9dc67d7fe9197` (Ruby 4.1.0dev) and on Ruby 3.3.1 (`c56cd86388`, arm64-darwin24). ## Cause and patch In `lazy_zip`, converted arguments are accumulated in `ary`. When a later argument does not convert to an Array, the fallback rebuilds `ary` from the original arguments, losing those conversions. Appending the remaining arguments to the converted prefix preserves the behavior of `Enumerable#zip`. Patch and regression tests: https://github.com/ruby/ruby/pull/19063 Both new regression tests fail before the fix (one failure and one error) and pass afterward. They cover conversion precedence, nil padding and repeated enumeration. After rebasing the fix onto master at `6eab8427a849dfe2e121b75faa30a272a8e4a1b3`, the related suites passed: 222 tests and 1,858 assertions (one skip for unavailable `callcc`), plus 439 specification examples with 687 expectations. The full Ruby test suite was not run. I found no matching report in the GitHub all-state and Redmine all-status searches performed. Related #7706 concerns the earlier lazy zip optimization and invalid-argument handling, rather than this conversion-loss case. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/