diff options
author | John Ankarström <john@ankarstrom.se> | 2021-05-05 20:02:23 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-05-05 20:02:23 +0200 |
commit | bdc020126a6b59f3a7b866ba72f6ca22a52f8e6c (patch) | |
tree | ce17b96a7dc3c4b737339d79c2d3dfc786231ffa /lib/List | |
download | List-Gather-Simple-bdc020126a6b59f3a7b866ba72f6ca22a52f8e6c.tar.gz |
Diffstat (limited to 'lib/List')
-rw-r--r-- | lib/List/Gather/Simple.pm | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/lib/List/Gather/Simple.pm b/lib/List/Gather/Simple.pm new file mode 100644 index 0000000..bf14952 --- /dev/null +++ b/lib/List/Gather/Simple.pm @@ -0,0 +1,129 @@ +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<gather>/C<take> construct in Perl 6/Raku. It differs from other +implementations in that it is, as the name suggests, very simple. + +C<gather> and C<take> are implemented as normal subroutines, operating +on a localized variable called C<@gathered>. All three of these +are imported when List::Gather::Simple is C<use>d. + +The benefit of exporting C<@gathered> as a variable (rather than a +subroutine called C<gathered>) is that C<@gathered> is very clearly +a normal Perl array, which can be used as an lvalue too, unlike the +C<gathered> 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<use warnings 'void'> is active and +C<gather> is called in void context. + +Note that the warning will be associated with the line on which +C<gather> is called. This can lead to the following unintuitive +behavior: If you return the results of C<gather> 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<gather> +call inside the subroutine. + +=item Exception: Call to 'take' outside of 'gather' + +This exception is raised if C<take> is called outside of a C<gather> +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<List::Gather> + +=item * +L<Perl6::Gather> + +=item * +L<Perl6::Take> + +=item * +L<Syntax::Keyword::Gather> + +=back + +=head1 AUTHOR + +John Ankarström, E<lt>john+spam@ankarstrom.seE<gt> (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 |