method pull-one
Documentation for method pull-one assembled from the following types:
role Iterator
From Iterator
(Iterator) method pull-one
Defined as:
method pull-one(Iterator:D: --> Mu)
This method stub ensures that classes implementing the Iterator role provide a method named pull-one.
The pull-one method is supposed to produce and return the next value if possible, or return the sentinel value IterationEnd if no more values could be produced.
my $i = (1 .. 3).iterator; say $i.pull-one; # OUTPUT: «1» say $i.pull-one; # OUTPUT: «2» say $i.pull-one; # OUTPUT: «3» say $i.pull-one.raku; # OUTPUT: «IterationEnd»
As a more illustrative example of its use, here is a count down iterator along with a simplistic subroutine re-implementation of the for loop.
# works the same as (10 ... 1, 'lift off')
class CountDown does Iterator {
has Int:D $!current = 10;
method pull-one ( --> Mu ) {
my $result = $!current--;
if $result == 0 { return 'lift off' }
if $result == -1 { return IterationEnd }
# calling .pull-one again after it returns IterationEnd is undefined
if $result <= -2 {
# so for fun we will give them nonsense data
return (1..10).pick;
}
return $result;
}
}
sub for( Iterable:D $sequence, &do --> Nil ) {
my Iterator:D $iterator = $sequence.iterator;
loop {
# must bind the result so that =:= works
my Mu $pulled := $iterator.pull-one;
# always check the result and make sure that .pull-one
# is not called again after it returns IterationEnd
if $pulled =:= IterationEnd { last }
do( $pulled );
}
}
for( Seq.new(CountDown.new), &say ); # OUTPUT: «10987654321lift off»
It would be more idiomatic to use while or until, and a sigilless variable.
until IterationEnd =:= (my \pulled = $iterator.pull-one) {
do( pulled );
}