1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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
|