class Enumerator[out T]
include Enumerable[T]
An external iterator over what a method yields: xs.each, xs.map,
xs.each_with_index, xs.each_slice(n), range.step(n) without a
block return one. It is Enumerable, so xs.each_with_index.map { }
works, and #with_index collects with an index (xs.map.with_index).
#next and #peek walk it one element at a time, from where the
source is: an array, a hash or a set (or a builder, by index as it is
then), an integer range (an endless one too) and Range#step, a
String range, Int#times, Int#upto, Int#downto and Int#step,
String#each_char, a subclass of Enumerator (below), and an
enumerator over one of these (each_with_index, each_slice,
each_cons, map, to_enum). A method written
in Quarz has no such position: its enumerator raises
NotImplementedError at #next, and its elements come through #each
and the Enumerable methods only. #each and the Enumerable methods
run the underlying method again from the start and do not move the
position of #next. An enumerator is not Shareable: it stays in the
task that made it.
A class of its own is an external iterator when it subclasses
Enumerator and defines #next, raising StopIteration past the last
element: #each, #with_index and the Enumerable methods then call
its #next (from where it is), and #peek, #rewind and #size
raise NotImplementedError unless it defines them too. Rewinding an
enumerator also rewinds its source when that is an object defining
rewind (such a subclass, say), as Ruby's does.
e = [1, 2].each
e.next # => 1
e.peek # => 2
e.next # => 2
e.next # raises StopIteration
e.rewind.next # => 1
(1..).each.next # => 1
class Countdown < Enumerator[Int]
var @n: Int
def initialize(@n: Int)
end
def next -> Int
raise StopIteration, "done" if @n == 0
@n -= 1
@n + 1
end
end
Countdown.new(3).to_a # => [3, 2, 1]
<prelude>:3737
Methods
def each(&: (T) -> Void) -> Void
Calls the block with each element, by calling the underlying method
from the start (leaving the position of #next as it is); a
subclass's by its #next.
<prelude>:3746
def next -> T
The element at the position, and moves past it.
Raises
StopIteration past the last element; NotImplementedError for a
source that is a method written in Quarz, and in a subclass that does
not define it.
<prelude>:3754
def peek -> T
The element at the position, without moving past it: what #next
would return.
Raises
As #next; NotImplementedError in a subclass that does not define
it.
<prelude>:3762
def rewind -> Self
Moves back to the first element, and returns the enumerator.
Raises
NotImplementedError in a subclass that does not define it.
<prelude>:3768
def size -> Int
The number of elements. Iterates over them (an endless source never returns).
Raises
NotImplementedError in a subclass that does not define it.
<prelude>:3775
def with_index[U](&: (T, Int) -> U) -> Array[U]
Collects the block's results: xs.map.with_index { |x, i| ... }.
The index starts at offset (0 without one).
%w[a b].each.with_index(1) { |s, i| "#{i}. #{s}" } # => ["1. a", "2. b"]
<prelude>:3783
def with_index[U](offset: Int, &: (T, Int) -> U) -> Array[U]
Collects the block's results: xs.map.with_index { |x, i| ... }.
The index starts at offset (0 without one).
%w[a b].each.with_index(1) { |s, i| "#{i}. #{s}" } # => ["1. a", "2. b"]
<prelude>:3785