summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/List/Util.pm
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2016-04-05 22:27:26 +0000
committerKarl Berry <karl@freefriends.org>2016-04-05 22:27:26 +0000
commitb56b320b5e2515160073fa1b469514002688fe11 (patch)
tree965a7100c5e45fca8ec803d22b8b6ce14fca4633 /Master/tlpkg/tlperl/lib/List/Util.pm
parentd26c206452d2e285c3bbf949f34011e4a55fd8f9 (diff)
tlperl 5.22.1 from siep
git-svn-id: svn://tug.org/texlive/trunk@40252 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlperl/lib/List/Util.pm')
-rw-r--r--Master/tlpkg/tlperl/lib/List/Util.pm195
1 files changed, 155 insertions, 40 deletions
diff --git a/Master/tlpkg/tlperl/lib/List/Util.pm b/Master/tlpkg/tlperl/lib/List/Util.pm
index 76b31be3c21..837b6c89a22 100644
--- a/Master/tlpkg/tlperl/lib/List/Util.pm
+++ b/Master/tlpkg/tlperl/lib/List/Util.pm
@@ -14,7 +14,7 @@ our @EXPORT_OK = qw(
all any first min max minstr maxstr none notall product reduce sum sum0 shuffle
pairmap pairgrep pairfirst pairs pairkeys pairvalues
);
-our $VERSION = "1.38";
+our $VERSION = "1.41";
our $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
@@ -34,6 +34,10 @@ sub import
goto &Exporter::import;
}
+# For objects returned by pairs()
+sub List::Util::_Pair::key { shift->[0] }
+sub List::Util::_Pair::value { shift->[1] }
+
1;
__END__
@@ -106,7 +110,11 @@ C<undef> being returned
The remaining list-reduction functions are all specialisations of this generic
idea.
-=head2 $b = any { BLOCK } @list
+=head2 any
+
+ my $bool = any { BLOCK } @list;
+
+I<Since version 1.33.>
Similar to C<grep> in that it evaluates C<BLOCK> setting C<$_> to each element
of C<@list> in turn. C<any> returns true if any element makes the C<BLOCK>
@@ -120,22 +128,34 @@ instead, as it can short-circuit after the first true result.
# at least one string has more than 10 characters
}
-=head2 $b = all { BLOCK } @list
+=head2 all
+
+ my $bool = all { BLOCK } @list;
+
+I<Since version 1.33.>
+
+Similar to L</any>, except that it requires all elements of the C<@list> to
+make the C<BLOCK> return true. If any element returns false, then it returns
+false. If the C<BLOCK> never returns false or the C<@list> was empty then it
+returns true.
-Similar to C<any>, except that it requires all elements of the C<@list> to make
-the C<BLOCK> return true. If any element returns false, then it returns false.
-If the C<BLOCK> never returns false or the C<@list> was empty then it returns
-true.
+=head2 none
-=head2 $b = none { BLOCK } @list
+=head2 notall
-=head2 $b = notall { BLOCK } @list
+ my $bool = none { BLOCK } @list;
-Similar to C<any> and C<all>, but with the return sense inverted. C<none>
-returns true only if no value in the LIST causes the BLOCK to return true, and
-C<notall> returns true only if not all of the values do.
+ my $bool = notall { BLOCK } @list;
-=head2 $val = first { BLOCK } @list
+I<Since version 1.33.>
+
+Similar to L</any> and L</all>, but with the return sense inverted. C<none>
+returns true only if no value in the C<@list> causes the C<BLOCK> to return
+true, and C<notall> returns true only if not all of the values do.
+
+=head2 first
+
+ my $val = first { BLOCK } @list;
Similar to C<grep> in that it evaluates C<BLOCK> setting C<$_> to each element
of C<@list> in turn. C<first> returns the first element where the result from
@@ -146,7 +166,9 @@ then C<undef> is returned.
$foo = first { $_ > $value } @list # first value in @list which
# is greater than $value
-=head2 $num = max @list
+=head2 max
+
+ my $num = max @list;
Returns the entry in the list with the highest numerical value. If the list is
empty then C<undef> is returned.
@@ -155,9 +177,11 @@ empty then C<undef> is returned.
$foo = max 3,9,12 # 12
$foo = max @bar, @baz # whatever
-=head2 $str = maxstr @list
+=head2 maxstr
+
+ my $str = maxstr @list;
-Similar to C<max>, but treats all the entries in the list as strings and
+Similar to L</max>, but treats all the entries in the list as strings and
returns the highest string as defined by the C<gt> operator. If the list is
empty then C<undef> is returned.
@@ -165,18 +189,22 @@ empty then C<undef> is returned.
$foo = maxstr "hello","world" # "world"
$foo = maxstr @bar, @baz # whatever
-=head2 $num = min @list
+=head2 min
+
+ my $num = min @list;
-Similar to C<max> but returns the entry in the list with the lowest numerical
+Similar to L</max> but returns the entry in the list with the lowest numerical
value. If the list is empty then C<undef> is returned.
$foo = min 1..10 # 1
$foo = min 3,9,12 # 3
$foo = min @bar, @baz # whatever
-=head2 $str = minstr @list
+=head2 minstr
-Similar to C<min>, but treats all the entries in the list as strings and
+ my $str = minstr @list;
+
+Similar to L</min>, but treats all the entries in the list as strings and
returns the lowest string as defined by the C<lt> operator. If the list is
empty then C<undef> is returned.
@@ -184,7 +212,11 @@ empty then C<undef> is returned.
$foo = minstr "hello","world" # "hello"
$foo = minstr @bar, @baz # whatever
-=head2 $num = product @list
+=head2 product
+
+ my $num = product @list;
+
+I<Since version 1.35.>
Returns the numerical product of all the elements in C<@list>. If C<@list> is
empty then C<1> is returned.
@@ -192,7 +224,9 @@ empty then C<1> is returned.
$foo = product 1..10 # 3628800
$foo = product 3,9,12 # 324
-=head2 $num_or_undef = sum @list
+=head2 sum
+
+ my $num_or_undef = sum @list;
Returns the numerical sum of all the elements in C<@list>. For backwards
compatibility, if C<@list> is empty then C<undef> is returned.
@@ -201,10 +235,14 @@ compatibility, if C<@list> is empty then C<undef> is returned.
$foo = sum 3,9,12 # 24
$foo = sum @bar, @baz # whatever
-=head2 $num = sum0 @list
+=head2 sum0
+
+ my $num = sum0 @list;
+
+I<Since version 1.26.>
-Similar to C<sum>, except this returns 0 when given an empty list, rather than
-C<undef>.
+Similar to L</sum>, except this returns 0 when given an empty list, rather
+than C<undef>.
=cut
@@ -218,9 +256,13 @@ value - nor even do they require that the first of each pair be a plain string.
=cut
-=head2 @kvlist = pairgrep { BLOCK } @kvlist
+=head2 pairgrep
-=head2 $count = pairgrep { BLOCK } @kvlist
+ my @kvlist = pairgrep { BLOCK } @kvlist;
+
+ my $count = pairgrep { BLOCK } @kvlist;
+
+I<Since version 1.29.>
Similar to perl's C<grep> keyword, but interprets the given list as an
even-sized list of pairs. It invokes the C<BLOCK> multiple times, in scalar
@@ -238,11 +280,15 @@ As with C<grep> aliasing C<$_> to list elements, C<pairgrep> aliases C<$a> and
C<$b> to elements of the given list. Any modifications of it by the code block
will be visible to the caller.
-=head2 ( $key, $val ) = pairfirst { BLOCK } @kvlist
+=head2 pairfirst
+
+ my ( $key, $val ) = pairfirst { BLOCK } @kvlist;
-=head2 $found = pairfirst { BLOCK } @kvlist
+ my $found = pairfirst { BLOCK } @kvlist;
-Similar to the C<first> function, but interprets the given list as an
+I<Since version 1.30.>
+
+Similar to the L</first> function, but interprets the given list as an
even-sized list of pairs. It invokes the C<BLOCK> multiple times, in scalar
context, with C<$a> and C<$b> set to successive pairs of values from the
C<@kvlist>.
@@ -258,9 +304,13 @@ As with C<grep> aliasing C<$_> to list elements, C<pairfirst> aliases C<$a> and
C<$b> to elements of the given list. Any modifications of it by the code block
will be visible to the caller.
-=head2 @list = pairmap { BLOCK } @kvlist
+=head2 pairmap
+
+ my @list = pairmap { BLOCK } @kvlist;
+
+ my $count = pairmap { BLOCK } @kvlist;
-=head2 $count = pairmap { BLOCK } @kvlist
+I<Since version 1.29.>
Similar to perl's C<map> keyword, but interprets the given list as an
even-sized list of pairs. It invokes the C<BLOCK> multiple times, in list
@@ -277,7 +327,13 @@ As with C<map> aliasing C<$_> to list elements, C<pairmap> aliases C<$a> and
C<$b> to elements of the given list. Any modifications of it by the code block
will be visible to the caller.
-=head2 @pairs = pairs @kvlist
+See L</KNOWN BUGS> for a known-bug with C<pairmap>, and a workaround.
+
+=head2 pairs
+
+ my @pairs = pairs @kvlist;
+
+I<Since version 1.29.>
A convenient shortcut to operating on even-sized lists of pairs, this function
returns a list of ARRAY references, each containing two items from the given
@@ -287,12 +343,25 @@ list. It is a more efficient version of
It is most convenient to use in a C<foreach> loop, for example:
- foreach ( pairs @KVLIST ) {
- my ( $key, $value ) = @$_;
+ foreach my $pair ( pairs @KVLIST ) {
+ my ( $key, $value ) = @$pair;
+ ...
+ }
+
+Since version C<1.39> these ARRAY references are blessed objects, recognising
+the two methods C<key> and C<value>. The following code is equivalent:
+
+ foreach my $pair ( pairs @KVLIST ) {
+ my $key = $pair->key;
+ my $value = $pair->value;
...
}
-=head2 @keys = pairkeys @kvlist
+=head2 pairkeys
+
+ my @keys = pairkeys @kvlist;
+
+I<Since version 1.29.>
A convenient shortcut to operating on even-sized lists of pairs, this function
returns a list of the the first values of each of the pairs in the given list.
@@ -300,7 +369,11 @@ It is a more efficient version of
@keys = pairmap { $a } @kvlist
-=head2 @values = pairvalues @kvlist
+=head2 pairvalues
+
+ my @values = pairvalues @kvlist;
+
+I<Since version 1.29.>
A convenient shortcut to operating on even-sized lists of pairs, this function
returns a list of the the second values of each of the pairs in the given list.
@@ -314,7 +387,9 @@ It is a more efficient version of
=cut
-=head2 @values = shuffle @values
+=head2 shuffle
+
+ my @values = shuffle @values;
Returns the values of the input in a random order
@@ -324,8 +399,48 @@ Returns the values of the input in a random order
=head1 KNOWN BUGS
-With perl versions prior to 5.005 there are some cases where reduce will return
-an incorrect result. This will show up as test 7 of reduce.t failing.
+=head2 RT #95409
+
+L<https://rt.cpan.org/Ticket/Display.html?id=95409>
+
+If the block of code given to L</pairmap> contains lexical variables that are
+captured by a returned closure, and the closure is executed after the block
+has been re-used for the next iteration, these lexicals will not see the
+correct values. For example:
+
+ my @subs = pairmap {
+ my $var = "$a is $b";
+ sub { print "$var\n" };
+ } one => 1, two => 2, three => 3;
+
+ $_->() for @subs;
+
+Will incorrectly print
+
+ three is 3
+ three is 3
+ three is 3
+
+This is due to the performance optimisation of using C<MULTICALL> for the code
+block, which means that fresh SVs do not get allocated for each call to the
+block. Instead, the same SV is re-assigned for each iteration, and all the
+closures will share the value seen on the final iteration.
+
+To work around this bug, surround the code with a second set of braces. This
+creates an inner block that defeats the C<MULTICALL> logic, and does get fresh
+SVs allocated each time:
+
+ my @subs = pairmap {
+ {
+ my $var = "$a is $b";
+ sub { print "$var\n"; }
+ }
+ } one => 1, two => 2, three => 3;
+
+This bug only affects closures that are generated by the block but used
+afterwards. Lexical variables that are only used during the lifetime of the
+block's execution will take their individual values for each invocation, as
+normal.
=head1 SUGGESTED ADDITIONS