aboutsummaryrefslogtreecommitdiff
path: root/lib/List/Gather/Simple.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/List/Gather/Simple.pm')
-rw-r--r--lib/List/Gather/Simple.pm129
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