Issue #7696 has been updated by marcandre (Marc-Andre Lafortune).


I had not see #6142. Yes, it's the same.

1) Add attr_accessor to Yielder and document the fact that the yielder is unique to a single enumeration run.

    def drop(n)
      n = Backports::coerce_to_int(n)
      Lazy.new(self) do |yielder, *values|
        yielder.memo ||= n
        if yielder.memo > 0
          yielder.memo -= 1
        else
          yielder.yield(*values)
        end
      end
    end

2) Optional named argument `prepare` for Lazy.new to be called before `each`:

    def drop(n)
      remain = nil
      Lazy.new(self, prepare: ->{remain = n}) do |yielder, *values|
        if remain > 0
          remain -= 1
        else
          yielder.yield(*values)
        end
      end
    end

3) Add a method 'prepare' method to Enumerator::Lazy and encourage subclassing. `prepare` would be called before `each`

    class LazyDropper < Enumerator::Lazy
      def initialize(obj, n)
        @n = n
        super do |yielder, *values|
          if @remain > 0
            @remain -= 1
          else
            yielder.yield(*values)
          end
       end

       def prepare
         @remain = @n
       end
    end

MRI should use the same kind of mechanism for the enums requiring state
----------------------------------------
Bug #7696: Lazy enumerators with state can't be rewound
https://bugs.ruby-lang.org/issues/7696#change-35449

Author: marcandre (Marc-Andre Lafortune)
Status: Open
Priority: High
Assignee: 
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/