From: "nuzair46 (Nuzair Rasheed) via ruby-core" Date: 2025-07-25T03:31:13+00:00 Subject: [ruby-core:122863] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek Issue #21520 has been updated by nuzair46 (Nuzair Rasheed). Dan0042 (Daniel DeLorme) wrote in #note-2: > #peek already exists, and does something different. Hey, Enumerator#peek exists. but Enumerator::Lazy#peek does not. Enumerator#peek [works differently](https://docs.ruby-lang.org/ja/latest/method/Enumerator/i/peek.html) than this suggestion. So maybe the naming will be confusing. ---------------------------------------- Feature #21520: Feature Proposal: Enumerator::Lazy#peek https://bugs.ruby-lang.org/issues/21520#change-114155 * Author: nuzair46 (Nuzair Rasheed) * Status: Open ---------------------------------------- # Abstract Add a #peek method to Enumerator::Lazy that allows observing each element in a lazy enumeration pipeline without modifying or consuming the stream. # Background Ruby provides Enumerator::Lazy for efficient lazy stream processing. However, unlike languages such as Java, it lacks a clean way to inspect intermediate elements during lazy evaluation. Currently, developers must misuse .map for side effects, example: ```rb (1..).lazy.map { |x| puts x; x }.select(&:even?).first(3) ``` This is semantically incorrect and confusing, since .map implies transformation, not observation. # Proposal Introduce Enumerator::Lazy#peek, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream: ```rb (1..).lazy .peek { |x| puts "saw: #{x}" } .select(&:even?) .first(3) ``` This would be equivalent to: ```rb lazy.map { |x| block.call(x); x } ``` but with improved semantic clarity. # Use cases ��� Debugging lazy enumerators without breaking the chain ��� Logging or instrumentation in pipelines ��� Educational / demo use for showing lazy evaluation step-by-step ��� Cleaner replacement for map { puts x; x } hacks Example: ```rb data = (1..).lazy .peek { |x| puts "got #{x}" } .select(&:even?) .first(5) ``` result: ```rb got 1 got 2 got 3 got 4 got 5 ... got 10 ``` And return [2, 4, 6, 8, 10] # Discussion #peek is a minimal, non-breaking addition that improves clarity and idiomatic usage of Enumerator::Lazy. It avoids abusing .map for observation and is familiar to developers from other languages. #peek is also not needed for other enumerators where .tap or .each can do the job. It mirrors Java���s .stream().peek(...) and makes Ruby���s lazy enumeration more expressive and readable. # See also ��� [Java Stream.peek](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-) I would be glad to work on this and make a PR. Thank you. -- 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/