[ruby-core:93117] [Ruby trunk Feature#15901] Enumerator::Lazy#eager
From:
ruby-core@...
Date:
2019-06-13 22:03:54 UTC
List:
ruby-core #93117
Issue #15901 has been updated by marcandre (Marc-Andre Lafortune).
zverok (Victor Shepelev) wrote:
> > How about this style?
>
> ```ruby
> [0, 1, 2].lazy {|e| e.map {|n| n + 1 }.map {|n| n.to_s } }
> #=> an Enumerator containing "1", "2", and "3"
> ```
>
> I believe that it defies the whole idea of lazy enumerators. instead of lazy enums being "just enums", it requires wrapping everything
I don't see how the suggestion defies anything, changes the current `lazy` method (without block) and or "requires" anything. It simply extends it with a block form that would automatically return an eager enumerator.
My issue with `lazy{}` is that it forces the user to return a lazy enumerator from the block (otherwise it raises?, e.g. `[1].lazy{ 42 } # => RuntimeError?`). The fact that the result could be completely unrelated is for me a design smell, e.g. `[1].lazy { [1, 2, 3].lazy }`.
I'm personally +1 for `eager`. I'd also alias `Enumerator#eager` to `#itself`.
----------------------------------------
Feature #15901: Enumerator::Lazy#eager
https://bugs.ruby-lang.org/issues/15901#change-78543
* Author: knu (Akinori MUSHA)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version:
----------------------------------------
There are cases where you want to create and pass a normal Enumerable object to a consumer where the methods like map and select are expected to return an array, but the calculation would be so space costly without using Enumerator::Lazy because of intermediate arrays. In such cases, you would want to chain `lazy` and calculation methods like `flat_map` and `select`, then convert the lazy enumerator back to a normal Enumerator.
However, there is no direct method that converts a lazy Enumerator to an eager one, because the` to_enum` method returns a lazy Enumerator when the receiver is a lazy Enumerator. So, I propose this `eager` method as the missing piece for the said use case.
Here's the rdoc from the attached patch.
```C
/*
* call-seq:
* lzy.eager -> enum
*
* Returns a non-lazy Enumerator converted from the lazy enumerator.
*
* This is useful where a normal Enumerable object needs to be
* generated while lazy operation is still desired to avoid creating
* intermediate arrays.
*
* enum = huge_collection.lazy.flat_map(&:children).reject(&:disabled?).eager
* enum.map {|x| ...} # an array is returned
*/
```
---Files--------------------------------
0001-Implement-Enumerator-Lazy-eager.patch (2.32 KB)
--
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>