=head1 NAME Generator::Object - Generator objects for Perl using Coro =head1 SYNOPSIS use strict; use warnings; use Generator::Object; my $gen = generator { my $x = 0; while (1) { $x += 2; $_->yield($x); } }; print $gen->next; # 2 print $gen->next; # 4 =head1 DESCRIPTION L provides a class for creating Python-like generators for Perl using C. Calling the C method will invoke the generator, while inside the generator body, calling the C method on the object will suspend the interpreter and return execution to the main thread. When C is called again the execution will return to the point of the C inside the generator body. Arguments passed to C are returned from C. This pattern allows for long-running processes to return values, possibly forever, with lazy evaluation. For convenience the generator object is provided to the function body as C<$_>. Further the context of the C method call is provided via the C object method. When/if the generator is exhausted, the C method will return C and the C method will return true. Any return value from the body will then be available from the C method. After the generator has reported that it is exhausted, another call to C will implicitly restart the generator. The generator may be restarted at any time by using the C method. C will be empty after the generator restarts. The internals of the object are entirely off-limits and where possible they have been hidden to prevent access. No subclass api is presented nor planned. The use of L internally shouldn't interfere with use of L externally. =head1 EXPORTS =head2 generator my $gen = generator { ...; $_->yield($val) while 1 }; Convenience function for creating instances of L. Takes a block (subref) which is the body of the generator. Returns an instance of L. =head1 CONSTRUCTOR =head2 new my $gen = Generator::Object->new(sub{...; $_->yield}); Takes a subref which is the body of the generator. Returns an instance of L. =head1 METHODS =head2 exhausted while (1) { next if defined $gen->next; print "Done\n" if $gen->exhausted; } When the generator is exhausted the C method will return C. However, since C might legitimately return C, this method is provided to check that the generator has indeed been exhausted. Note that if C is called on an exhausted generator, it is restarted, and thus C will again return a false value. =head2 next my $first = $gen->next; my $second = $gen->next; This method iterates the generator until C is called or the body is returned from. It returns any value passed to C, in list context all arguments are returned, in scalar context the first argument is returned. This emulates returning a list. The context of the C call is available from the C method for more manual control. When the generator is exhausted, that is to say, when the body function returns, C returns C. Check C to differentiate between exhaustion and a yielded C. Any values returned from the body are available via the C method, again list return is emulated and the C method (of the final C call) can be checked when returning. =head2 restart my $gen = generator { my $x = 1; $_->yield($x++) while 1 }; my $first = $gen->next; $gen->restart; $first == $gen->next; # true Restarts the generator to its initial state. Of course if your generator has made external changes, those will remain. Any values in C are cleared and C is reset (if applicable). C is implicitly called when C is invoked on an exhasted generator. =head2 retval my $gen = generator { return 'val' }; $gen->next; my $val = $gen->retval; # 'val' Returns the value or values returned from the generator upon exhaustion if any. In list context all returned values are given, in scalar context the first element is returned. This emulates returning a list. Note that the context in which C was called as the generator is exhausted is available via the C method for manual control. =head2 wantarray my $gen = generator { while (1) { $_->wantarray ? $_->yield('next called in list context') : $_->yield('next called in scalar context'); } } my ($list) = $gen->next; my $scalar = $gen->next; Much like the Perl built-in of the same name, this method provides the context in which the C method is called, making that information available to the generator body. =head2 yield my $gen = generator { ...; $_->yield($val) while 1 }; This method is the guts of the generator. When called C suspends the state of the interpreter as it exists inside the generator body and returns to the point at which C was called. The values passed will be returned by C (see its documentation for more). This method should not be called outside the generator body. For now, doing so dies. In the future though this might change to be a safer no-op in the future, or else the method may only be made available inside the body as safe-guards. In the meantime, just don't do it! =head1 FUTURE WORK I intend (possibly soon) to allow arguments to be passed to the generator body possibly even on every call to C. Stay tuned. =head1 SEE ALSO =over =item L =back A few similar modules already exist. Their API and design choices weren't to my liking, but they may appeal to you. Certainly I used them as reference and thanks are due. =over =item L =item L =back =head1 SOURCE REPOSITORY L =head1 AUTHOR Joel Berger, Ejoel.a.berger@gmail.comE =head1 COPYRIGHT AND LICENSE Copyright (C) 2013 by Joel Berger This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 1;