Generator-Object
view release on metacpan or search on metacpan
lib/Generator/Object.pm view on Meta::CPAN
sub next {
my $self = shift;
return undef if $self->exhausted;
# protect some state values from leaking
local $self->{orig} = $Coro::current;
local $self->{wantarray} = wantarray;
local $self->{yieldval};
$self->{coro} = Coro->new(sub {
local $_ = $self;
$self->{retval} = [ $self->{sub}->() ];
$self->{exhausted} = 1;
$self->{orig}->schedule_to;
}) unless $self->{coro};
$self->{coro}->schedule_to;
my $yield = $self->{yieldval} || [];
return $self->{wantarray} ? @$yield : $yield->[0];
}
=head2 restart
my $gen = generator { my $x = 1; $_->yield($x++) while 1 };
my $first = $gen->next;
$gen->restart;
lib/Generator/Object.pm view on Meta::CPAN
Note: C<restart> is no longer implicitly called when C<next> is invoked on an
exhasted generator. You may recreate the old behavior by simply doing
$gen->restart if $gen->exhausted;
=cut
sub restart {
my $self = shift;
delete $self->{coro};
delete $self->{exhausted};
$self->{retval} = [];
}
=head2 retval
my $gen = generator { return 'val' };
$gen->next;
my $val = $gen->retval; # 'val'
};
subtest 'Simple Context (alpha)' => sub {
is_deeply [$alpha->next], [qw/a b c/], 'right result (list)';
is_deeply [$alpha->next], [qw/b c d/], 'right result (list)';
is scalar $alpha->next, 'c', 'right result (scalar)';
};
subtest 'Interference' => sub {
# when the two coroutines are both called, this will be more than 6
# since the even coro was entered when alpha cedes
is $evens->next, 6, 'right result (even)';
is $alpha->next, 'd', 'right result (alpha)';
};
$evens->restart;
is $evens->next, 2, 'restart';
eval{ $evens->yield };
ok $@, 'yield outside generator dies';
( run in 0.480 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )