* [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
@ 2025-07-24 2:37 nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 2:47 ` [ruby-core:122848] " nuzair46 (Nuzair Rasheed) via ruby-core
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-07-24 2:37 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been reported by nuzair46 (Nuzair Rasheed).
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#peek
https://bugs.ruby-lang.org/issues/21520
* 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
```
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122848] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-07-24 2:47 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 14:07 ` [ruby-core:122855] " Dan0042 (Daniel DeLorme) via ruby-core
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-07-24 2:47 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
# 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.
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#peek
https://bugs.ruby-lang.org/issues/21520#change-114137
* 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
```
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122855] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 2:47 ` [ruby-core:122848] " nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-07-24 14:07 ` Dan0042 (Daniel DeLorme) via ruby-core
2025-07-25 3:31 ` [ruby-core:122863] " nuzair46 (Nuzair Rasheed) via ruby-core
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Dan0042 (Daniel DeLorme) via ruby-core @ 2025-07-24 14:07 UTC (permalink / raw)
To: ruby-core; +Cc: Dan0042 (Daniel DeLorme)
Issue #21520 has been updated by Dan0042 (Daniel DeLorme).
#peek already exists, and does something different.
I think #each should work in the way this proposal describes. I was a bit surprised that the code below resulted in an infinite loop rather than a lazy enumeration.
```ruby
(1..).lazy.each{ |x| puts x }.select(&:even?).first(3)
```
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#peek
https://bugs.ruby-lang.org/issues/21520#change-114146
* 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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122863] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 2:47 ` [ruby-core:122848] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 14:07 ` [ruby-core:122855] " Dan0042 (Daniel DeLorme) via ruby-core
@ 2025-07-25 3:31 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-28 2:44 ` [ruby-core:122870] " nuzair46 (Nuzair Rasheed) via ruby-core
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-07-25 3:31 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122870] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (2 preceding siblings ...)
2025-07-25 3:31 ` [ruby-core:122863] " nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-07-28 2:44 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-29 7:02 ` [ruby-core:122880] " nobu (Nobuyoshi Nakada) via ruby-core
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-07-28 2:44 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
nuzair46 (Nuzair Rasheed) wrote in #note-3:
> 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.
Running the whole CI, I see the collision with Enumerator#peek.
So I think the name should be changed to avoid confusion and collision.
Im thinking `spy` or `tap_each`
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#peek
https://bugs.ruby-lang.org/issues/21520#change-114171
* 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122880] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (3 preceding siblings ...)
2025-07-28 2:44 ` [ruby-core:122870] " nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-07-29 7:02 ` nobu (Nobuyoshi Nakada) via ruby-core
2025-07-30 5:42 ` [ruby-core:122882] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each nuzair46 (Nuzair Rasheed) via ruby-core
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nobu (Nobuyoshi Nakada) via ruby-core @ 2025-07-29 7:02 UTC (permalink / raw)
To: ruby-core; +Cc: nobu (Nobuyoshi Nakada)
Issue #21520 has been updated by nobu (Nobuyoshi Nakada).
Or `lazy_each`?
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#peek
https://bugs.ruby-lang.org/issues/21520#change-114183
* 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122882] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (4 preceding siblings ...)
2025-07-29 7:02 ` [ruby-core:122880] " nobu (Nobuyoshi Nakada) via ruby-core
@ 2025-07-30 5:42 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-05 2:30 ` [ruby-core:122913] " nuzair46 (Nuzair Rasheed) via ruby-core
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-07-30 5:42 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
Subject changed from Feature Proposal: Enumerator::Lazy#peek to Feature Proposal: Enumerator::Lazy#lazy_each
Description updated
updated to `lazy_each`
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#lazy_each
https://bugs.ruby-lang.org/issues/21520#change-114186
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #lazy_each 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#lazy_each, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.lazy_each { |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
.lazy_each { |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
#lazy_each 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. #lazy_each 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:122913] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (5 preceding siblings ...)
2025-07-30 5:42 ` [ruby-core:122882] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-08-05 2:30 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-21 8:15 ` [ruby-core:123002] " nobu (Nobuyoshi Nakada) via ruby-core
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-08-05 2:30 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
The PR is open for review https://github.com/ruby/ruby/pull/14024
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#lazy_each
https://bugs.ruby-lang.org/issues/21520#change-114217
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #lazy_each 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#lazy_each, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.lazy_each { |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
.lazy_each { |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
#lazy_each 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. #lazy_each 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:123002] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (6 preceding siblings ...)
2025-08-05 2:30 ` [ruby-core:122913] " nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-08-21 8:15 ` nobu (Nobuyoshi Nakada) via ruby-core
2025-08-21 8:28 ` [ruby-core:123004] " nuzair46 (Nuzair Rasheed) via ruby-core
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nobu (Nobuyoshi Nakada) via ruby-core @ 2025-08-21 8:15 UTC (permalink / raw)
To: ruby-core; +Cc: nobu (Nobuyoshi Nakada)
Issue #21520 has been updated by nobu (Nobuyoshi Nakada).
A couple days ago, another name came to me: `tee`.
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#lazy_each
https://bugs.ruby-lang.org/issues/21520#change-114304
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #lazy_each 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#lazy_each, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.lazy_each { |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
.lazy_each { |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
#lazy_each 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. #lazy_each 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:123004] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (7 preceding siblings ...)
2025-08-21 8:15 ` [ruby-core:123002] " nobu (Nobuyoshi Nakada) via ruby-core
@ 2025-08-21 8:28 ` nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-21 9:16 ` [ruby-core:123008] " matz (Yukihiro Matsumoto) via ruby-core
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-08-21 8:28 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
nobu (Nobuyoshi Nakada) wrote in #note-9:
> A couple days ago, another name came to me: `tee`.
Thanks, `tee` is a great fit. It’s short and feels very Unix-y. I will make changes to the PR and the proposal soon.
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#lazy_each
https://bugs.ruby-lang.org/issues/21520#change-114306
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #lazy_each 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#lazy_each, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.lazy_each { |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
.lazy_each { |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
#lazy_each 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. #lazy_each 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:123008] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (8 preceding siblings ...)
2025-08-21 8:28 ` [ruby-core:123004] " nuzair46 (Nuzair Rasheed) via ruby-core
@ 2025-08-21 9:16 ` matz (Yukihiro Matsumoto) via ruby-core
2025-08-21 9:30 ` [ruby-core:123012] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#tee nuzair46 (Nuzair Rasheed) via ruby-core
2026-02-17 5:12 ` [ruby-core:124842] " nuzair46 (Nuzair Rasheed) via ruby-core
11 siblings, 0 replies; 13+ messages in thread
From: matz (Yukihiro Matsumoto) via ruby-core @ 2025-08-21 9:16 UTC (permalink / raw)
To: ruby-core; +Cc: matz (Yukihiro Matsumoto)
Issue #21520 has been updated by matz (Yukihiro Matsumoto).
I don't think `lazy_each` is a good name. We just wanted to peek the element in the stream, being lazy or not. In that sense, `tee` is better, if you are familiar with UNIX (like me).
Matz.
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#lazy_each
https://bugs.ruby-lang.org/issues/21520#change-114310
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #lazy_each 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#lazy_each, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.lazy_each { |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
.lazy_each { |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
#lazy_each 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. #lazy_each 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:123012] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#tee
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (9 preceding siblings ...)
2025-08-21 9:16 ` [ruby-core:123008] " matz (Yukihiro Matsumoto) via ruby-core
@ 2025-08-21 9:30 ` nuzair46 (Nuzair Rasheed) via ruby-core
2026-02-17 5:12 ` [ruby-core:124842] " nuzair46 (Nuzair Rasheed) via ruby-core
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2025-08-21 9:30 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
matz (Yukihiro Matsumoto) wrote in #note-11:
> I don't think `lazy_each` is a good name. We just wanted to peek the element in the stream, being lazy or not. In that sense, `tee` is better, if you are familiar with UNIX (like me).
>
> Matz.
Thanks Matz. I have updated the PR and proposal with the name #tee for the method.
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#tee
https://bugs.ruby-lang.org/issues/21520#change-114316
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #tee 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#tee, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.tee { |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
.tee { |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
#tee 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. #tee 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [ruby-core:124842] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#tee
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
` (10 preceding siblings ...)
2025-08-21 9:30 ` [ruby-core:123012] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#tee nuzair46 (Nuzair Rasheed) via ruby-core
@ 2026-02-17 5:12 ` nuzair46 (Nuzair Rasheed) via ruby-core
11 siblings, 0 replies; 13+ messages in thread
From: nuzair46 (Nuzair Rasheed) via ruby-core @ 2026-02-17 5:12 UTC (permalink / raw)
To: ruby-core; +Cc: nuzair46 (Nuzair Rasheed)
Issue #21520 has been updated by nuzair46 (Nuzair Rasheed).
Just checking in on this feature. Is there anything missing from the current implementation that would help move it forward?
----------------------------------------
Feature #21520: Feature Proposal: Enumerator::Lazy#tee
https://bugs.ruby-lang.org/issues/21520#change-116496
* Author: nuzair46 (Nuzair Rasheed)
* Status: Open
----------------------------------------
# Abstract
Add a #tee 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#tee, which yields each item to a block and returns the item unmodified, similar to Object#tap, but in a lazy stream:
```rb
(1..).lazy
.tee { |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
.tee { |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
#tee 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. #tee 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 have a draft PR for the implementation ready https://github.com/ruby/ruby/pull/14024
--
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/
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-02-17 5:12 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-24 2:37 [ruby-core:122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 2:47 ` [ruby-core:122848] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-24 14:07 ` [ruby-core:122855] " Dan0042 (Daniel DeLorme) via ruby-core
2025-07-25 3:31 ` [ruby-core:122863] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-28 2:44 ` [ruby-core:122870] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-07-29 7:02 ` [ruby-core:122880] " nobu (Nobuyoshi Nakada) via ruby-core
2025-07-30 5:42 ` [ruby-core:122882] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#lazy_each nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-05 2:30 ` [ruby-core:122913] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-21 8:15 ` [ruby-core:123002] " nobu (Nobuyoshi Nakada) via ruby-core
2025-08-21 8:28 ` [ruby-core:123004] " nuzair46 (Nuzair Rasheed) via ruby-core
2025-08-21 9:16 ` [ruby-core:123008] " matz (Yukihiro Matsumoto) via ruby-core
2025-08-21 9:30 ` [ruby-core:123012] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#tee nuzair46 (Nuzair Rasheed) via ruby-core
2026-02-17 5:12 ` [ruby-core:124842] " nuzair46 (Nuzair Rasheed) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).