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'

t/basic.t  view on Meta::CPAN

};

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.314 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )