package List::Gather::Simple; use 5.006; use warnings; use strict; no strict 'refs'; use Carp; use Exporter qw/import/; our $VERSION = '0.01'; our @EXPORT = qw/gather take @gathered/; our $gathering; sub gather (&) { my ($code, $pkg) = (shift, caller); local @{"${pkg}::gathered"}; local $gathering = 1; &$code; warnings::warnif 'void', "Useless use of 'gather' in void context" if not defined wantarray; return @{"${pkg}::gathered"}; } sub take (@) { croak "Call to 'take' outside of 'gather'" if not $gathering; @_ = $_ if not @_; my $pkg = caller; push @{"${pkg}::gathered"}, @_; return @_; } 1; __END__ =encoding utf8 =head1 NAME List::Gather::Simple - Simple implementation of gather/take =head1 SYNOPSIS use List::Gather::Simple; print gather { take for gather { take 'Hello ', 'world!'; }; unshift @gathered, 'Test message: '; }, "\n"; # -> Test message: Hello world! =head1 DESCRIPTION List::Gather::Simple is yet another Perl 5 implementation of the C/C construct in Perl 6/Raku. It differs from other implementations in that it is, as the name suggests, very simple. C and C are implemented as normal subroutines, operating on a localized variable called C<@gathered>. All three of these are imported when List::Gather::Simple is Cd. The benefit of exporting C<@gathered> as a variable (rather than a subroutine called C) is that C<@gathered> is very clearly a normal Perl array, which can be used as an lvalue too, unlike the C subroutine of other implementations. That means that the following is valid: gather { @gathered = merge(@gathered, @x) while @x } =head1 DIAGNOSTICS =over =item Warning: Useless use of 'gather' in void context This warning is issued if C is active and C is called in void context. Note that the warning will be associated with the line on which C is called. This can lead to the following unintuitive behavior: If you return the results of C from a subroutine and then call that subroutine in void context, the warning will still be issued, but it will refer to the line of the C call inside the subroutine. =item Exception: Call to 'take' outside of 'gather' This exception is raised if C is called outside of a C block. Note that this is a runtime error. =back =head1 SEE ALSO All of the following modules have inspired List::Gather::Simple: =over =item * L =item * L =item * L =item * L =back =head1 AUTHOR John Ankarström, Ejohn+spam@ankarstrom.seE (remove +spam) =head1 COPYRIGHT AND LICENSE Copyright (C) 2021 by John Ankarström This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.32.1 or, at your option, any later version of Perl 5 you may have available. =cut