Issue #15901 has been updated by knu (Akinori MUSHA).


> One argument would be the callee should do take_while {}.to_a if they really want an Array and not just an Enumerable (which has most of Array's methods).
> But I understand it's nice to be able to use an unmodified library and not needing the library to know about Enumerator::Lazy.

Yeah, that would be the way completely against duck-typing.  In my opinion, Enumerator::Lazy objects should only be used locally not to be passed around, because it claims to be Enumerable but does not work exactly the same as other Enumerable objects, requiring others to take special care of them.

With `eager` added, you could consider Lazy as a DSL for generating a memory efficient enumerator that is compatible with any Enumerable friendly method with this idiom: `enum.lazy.method{}.chain{}.eager`.

----------------------------------------
Feature #15901: Enumerator::Lazy#eager
https://bugs.ruby-lang.org/issues/15901#change-78386

* Author: knu (Akinori MUSHA)
* Status: Open
* Priority: Normal
* Assignee: 
* 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>