Issue #7696 has been updated by shugo (Shugo Maeda).

Assignee set to matz (Yukihiro Matsumoto)

marcandre (Marc-Andre Lafortune) wrote:
> shugo (Shugo Maeda) wrote:
> > So, the following behavior is intended, right?
> > 
> >   $ ruby1.9.3 -I ~/src/backports/lib  -r backports -r backports/2.0.0/enumerable -e "a = (1..3).lazy.zip(('a'..'z').each); p a.to_a; p a.to_a"
> >   [[1, "a"], [2, "b"], [3, "c"]]
> >   [[1, "d"], [2, "e"], [3, "f"]]
> 
> That's a very good question.
> 
> It probably would be best to call `to_enum` instead of `each`. Calling `next|rewind` on an enumerator should really only affect other calls to `next`. With `to_enum`, we'll get the same result every time.

Even if to_enum is called, IO instances never be rewound, but I guess IO instances need not be rewound.

> > It might be too late to introduce a new API for 2.0.0, so how about to move it to next minor?
> 
> I understand. On the other hand, the API for Lazy.new was never decided upon and really should be finalized before 2.0.0!
> 
> If we opt for the Yielder#memo way (and agree on the name), maybe we can convince mame to accept such a trivial change. In that case, the biggest "change" is the explicit guarantee of a different yielder per iteration. It's already the case (also for JRuby and rubinius), but AFAIK it's never been official.

`The explicit guarantee of a different yielder per iteration' sounds acceptable for me, but I'm not sure whether Yielder#memo is a good name.

> With the modified yielding way, it would be nice to include it in Lazy.new's api in this version, especially since it is still being finalized.
> 
> At the very least, a note in the documentation about handling state would be needed for 2.0.0.

I believe Matz should decide it.

----------------------------------------
Bug #7696: Lazy enumerators with state can't be rewound
https://bugs.ruby-lang.org/issues/7696#change-35519

Author: marcandre (Marc-Andre Lafortune)
Status: Open
Priority: High
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0
ruby -v: r38800


The 4 lazy enumerators requiring internal state, i.e. {take|drop}{_while}, don't work as expected after a couple `next` and a call to `rewind`.

For example:

    e=(1..42).lazy.take(2)
    e.next # => 1
    e.next # => 2
    e.rewind
    e.next # => 1
    e.next # => StopIteration: iteration reached an end, expected 2

This is related to #7691; the current API does not give an easy way to handle state.

Either there's a dedicated callback to rewind, or data must be attached to the yielder.


-- 
http://bugs.ruby-lang.org/