diff options
author | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-06-05 16:16:27 +0100 |
---|---|---|
committer | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-06-05 16:16:27 +0100 |
commit | b823713ce3ee6bfd4d009e6307703c7d2e63b7c8 (patch) | |
tree | 4b706cdfaa89d83492394fa5d74bad4dad72e3f4 /cpan/Scalar-List-Utils | |
parent | a7ab896004fe7cc32eeddadf760d0829e9fed13d (diff) | |
download | perl-b823713ce3ee6bfd4d009e6307703c7d2e63b7c8.tar.gz |
Update Scalar-List-Utils to CPAN version 1.39
[DELTA]
1.39 -- 2014/06/05 15:54:59
[CHANGES]
* Have pairs() return blessed objects that recognise ->key and
->value as well as being two-element ARRAYs
* Booleanise the result of looks_like_number() so as not to
accidentally leak abstraction (RT94806)
* Document the version each function was added in (RT96220)
[BUGFIXES]
* Try to preserve UV precision in sum() where possible (RT95902)
* Document known lexical capture in pairmap bug RT95409
* SvGETMAGIC() in set_prototype() (RT72080)
Diffstat (limited to 'cpan/Scalar-List-Utils')
31 files changed, 320 insertions, 376 deletions
diff --git a/cpan/Scalar-List-Utils/ListUtil.xs b/cpan/Scalar-List-Utils/ListUtil.xs index 20551930e9..e6a2eaa673 100644 --- a/cpan/Scalar-List-Utils/ListUtil.xs +++ b/cpan/Scalar-List-Utils/ListUtil.xs @@ -66,6 +66,22 @@ my_sv_copypv(pTHX_ SV *const dsv, SV *const ssv) # define croak_no_modify() croak("%s", PL_no_modify) #endif +enum slu_accum { + ACC_IV, + ACC_NV, + ACC_SV, +}; + +static enum slu_accum accum_type(SV *sv) { + if(SvAMAGIC(sv)) + return ACC_SV; + + if(SvIOK(sv) && !SvNOK(sv) && !SvUOK(sv)) + return ACC_IV; + + return ACC_NV; +} + MODULE=List::Util PACKAGE=List::Util void @@ -129,11 +145,13 @@ CODE: { dXSTARG; SV *sv; + IV retiv = 0; + NV retnv = 0.0; SV *retsv = NULL; int index; - NV retval = 0; - int magic; + enum slu_accum accum; int is_product = (ix == 2); + SV *tmpsv; if(!items) switch(ix) { @@ -143,52 +161,88 @@ CODE: } sv = ST(0); - magic = SvAMAGIC(sv); - if(magic) { + switch((accum = accum_type(sv))) { + case ACC_SV: retsv = TARG; sv_setsv(retsv, sv); - } - else { - retval = slu_sv_value(sv); + break; + case ACC_IV: + retiv = SvIV(sv); + break; + case ACC_NV: + retnv = slu_sv_value(sv); + break; } for(index = 1 ; index < items ; index++) { sv = ST(index); - if(!magic && SvAMAGIC(sv)){ - magic = TRUE; + if(accum < ACC_SV && SvAMAGIC(sv)){ if(!retsv) retsv = TARG; - sv_setnv(retsv,retval); + sv_setnv(retsv, accum == ACC_NV ? retnv : retiv); + accum = ACC_SV; } - if(magic) { - SV *const tmpsv = amagic_call(retsv, sv, + switch(accum) { + case ACC_SV: + tmpsv = amagic_call(retsv, sv, is_product ? mult_amg : add_amg, SvAMAGIC(retsv) ? AMGf_assign : 0); if(tmpsv) { - magic = SvAMAGIC(tmpsv); - if(!magic) { - retval = slu_sv_value(tmpsv); - } - else { + switch((accum = accum_type(tmpsv))) { + case ACC_SV: retsv = tmpsv; + break; + case ACC_IV: + retiv = SvIV(tmpsv); + break; + case ACC_NV: + retnv = slu_sv_value(tmpsv); + break; } } else { /* fall back to default */ - magic = FALSE; - is_product ? (retval = SvNV(retsv) * SvNV(sv)) - : (retval = SvNV(retsv) + SvNV(sv)); + accum = ACC_NV; + is_product ? (retnv = SvNV(retsv) * SvNV(sv)) + : (retnv = SvNV(retsv) + SvNV(sv)); } - } - else { - is_product ? (retval *= slu_sv_value(sv)) - : (retval += slu_sv_value(sv)); + break; + case ACC_IV: + if(is_product) { + if(!SvNOK(sv) && SvIOK(sv) && (SvIV(sv) < IV_MAX / retiv)) { + retiv *= SvIV(sv); + break; + } + /* else fallthrough */ + } + else { + if(!SvNOK(sv) && SvIOK(sv) && (SvIV(sv) < IV_MAX - retiv)) { + retiv += SvIV(sv); + break; + } + /* else fallthrough */ + } + + /* fallthrough to NV now */ + retnv = retiv; + accum = ACC_NV; + case ACC_NV: + is_product ? (retnv *= slu_sv_value(sv)) + : (retnv += slu_sv_value(sv)); + break; } } - if(!magic) { - if(!retsv) - retsv = TARG; - sv_setnv(retsv,retval); + + if(!retsv) + retsv = TARG; + + switch(accum) { + case ACC_IV: + sv_setiv(retsv, retiv); + break; + case ACC_NV: + sv_setnv(retsv, retnv); + break; } ST(0) = retsv; @@ -715,6 +769,7 @@ PPCODE: { int argi = 0; int reti = 0; + HV *pairstash = get_hv("List::Util::_Pair::", GV_ADD); if(items % 2 && ckWARN(WARN_MISC)) warn("Odd number of elements in pairs"); @@ -728,7 +783,9 @@ PPCODE: av_push(av, newSVsv(a)); av_push(av, newSVsv(b)); - ST(reti++) = sv_2mortal(newRV_noinc((SV *)av)); + ST(reti) = sv_2mortal(newRV_noinc((SV *)av)); + sv_bless(ST(reti), pairstash); + reti++; } } @@ -1019,13 +1076,13 @@ CODE: } #if PERL_BCDVERSION < 0x5008005 if(SvPOK(sv) || SvPOKp(sv)) { - RETVAL = looks_like_number(sv); + RETVAL = !!looks_like_number(sv); } else { RETVAL = SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK); } #else - RETVAL = looks_like_number(sv); + RETVAL = !!looks_like_number(sv); #endif OUTPUT: RETVAL @@ -1037,6 +1094,7 @@ set_prototype(subref, proto) PROTOTYPE: &$ CODE: { + SvGETMAGIC(subref); if(SvROK(subref)) { SV *sv = SvRV(subref); if(SvTYPE(sv) != SVt_PVCV) { diff --git a/cpan/Scalar-List-Utils/lib/List/Util.pm b/cpan/Scalar-List-Utils/lib/List/Util.pm index 76b31be3c2..c99bcd41ee 100644 --- a/cpan/Scalar-List-Utils/lib/List/Util.pm +++ b/cpan/Scalar-List-Utils/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.39"; 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__ @@ -108,6 +112,8 @@ idea. =head2 $b = 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> return a true value. If C<BLOCK> never returns true or C<@list> was empty then @@ -122,6 +128,8 @@ instead, as it can short-circuit after the first true result. =head2 $b = all { BLOCK } @list +I<Since version 1.33.> + 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 @@ -131,6 +139,8 @@ true. =head2 $b = notall { BLOCK } @list +I<Since version 1.33.> + 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. @@ -186,6 +196,8 @@ empty then C<undef> is returned. =head2 $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. @@ -203,6 +215,8 @@ compatibility, if C<@list> is empty then C<undef> is returned. =head2 $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>. @@ -222,6 +236,8 @@ value - nor even do they require that the first of each pair be a plain string. =head2 $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 context, with C<$a> and C<$b> set to successive pairs of values from the @@ -242,6 +258,8 @@ will be visible to the caller. =head2 $found = pairfirst { BLOCK } @kvlist +I<Since version 1.30.> + Similar to the C<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 @@ -262,6 +280,8 @@ will be visible to the caller. =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 context, with C<$a> and C<$b> set to successive pairs of values from the @@ -277,8 +297,12 @@ 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. +See L</KNOWN BUGS> for a known-bug with C<pairmap>, and a workaround. + =head2 @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 list. It is a more efficient version of @@ -287,13 +311,24 @@ 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 +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. It is a more efficient version of @@ -302,6 +337,8 @@ It is a more efficient version of =head2 @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. It is a more efficient version of @@ -324,8 +361,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 C<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 diff --git a/cpan/Scalar-List-Utils/lib/List/Util/XS.pm b/cpan/Scalar-List-Utils/lib/List/Util/XS.pm index 32c10972aa..e605d88e3d 100644 --- a/cpan/Scalar-List-Utils/lib/List/Util/XS.pm +++ b/cpan/Scalar-List-Utils/lib/List/Util/XS.pm @@ -2,7 +2,7 @@ package List::Util::XS; use strict; use List::Util; -our $VERSION = "1.38"; # FIXUP +our $VERSION = "1.39"; # FIXUP $VERSION = eval $VERSION; # FIXUP 1; diff --git a/cpan/Scalar-List-Utils/lib/Scalar/Util.pm b/cpan/Scalar-List-Utils/lib/Scalar/Util.pm index 4ab67f9aa0..06d3660469 100644 --- a/cpan/Scalar-List-Utils/lib/Scalar/Util.pm +++ b/cpan/Scalar-List-Utils/lib/Scalar/Util.pm @@ -16,7 +16,7 @@ our @EXPORT_OK = qw( dualvar isdual isvstring looks_like_number openhandle readonly set_prototype tainted ); -our $VERSION = "1.38"; +our $VERSION = "1.39"; $VERSION = eval $VERSION; our @EXPORT_FAIL; @@ -156,6 +156,8 @@ array. =head2 unweaken( REF ) +I<Since version 1.36.> + The lvalue C<REF> will be turned from a weak reference back into a normal (strong) reference again. This function mutates the lvalue passed as its argument and returns no value. This undoes the action performed by @@ -198,6 +200,8 @@ C<$string> in a string context. =head2 $dual = isdual( $var ) +I<Since version 1.26.> + If C<$var> is a scalar that has both numeric and string values, the result is true. diff --git a/cpan/Scalar-List-Utils/t/00version.t b/cpan/Scalar-List-Utils/t/00version.t index d475de488d..b04bd33e0d 100644 --- a/cpan/Scalar-List-Utils/t/00version.t +++ b/cpan/Scalar-List-Utils/t/00version.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Scalar::Util (); use List::Util (); diff --git a/cpan/Scalar-List-Utils/t/any-all.t b/cpan/Scalar-List-Utils/t/any-all.t index 6fbf89a6ec..f1626c23d8 100644 --- a/cpan/Scalar-List-Utils/t/any-all.t +++ b/cpan/Scalar-List-Utils/t/any-all.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use List::Util qw(any all notall none); use Test::More tests => 12; diff --git a/cpan/Scalar-List-Utils/t/blessed.t b/cpan/Scalar-List-Utils/t/blessed.t index ae292b9954..21d3a9ade4 100644 --- a/cpan/Scalar-List-Utils/t/blessed.t +++ b/cpan/Scalar-List-Utils/t/blessed.t @@ -1,21 +1,12 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Test::More tests => 11; use Scalar::Util qw(blessed); -use vars qw($t $x); + +my $t; ok(!defined blessed(undef), 'undef is not blessed'); ok(!defined blessed(1), 'Numbers are not blessed'); @@ -24,6 +15,8 @@ ok(!defined blessed({}), 'Unblessed HASH-ref'); ok(!defined blessed([]), 'Unblessed ARRAY-ref'); ok(!defined blessed(\$t), 'Unblessed SCALAR-ref'); +my $x; + $x = bless [], "ABC"; is(blessed($x), "ABC", 'blessed ARRAY-ref'); diff --git a/cpan/Scalar-List-Utils/t/dualvar.t b/cpan/Scalar-List-Utils/t/dualvar.t index 0943c75545..08dff11778 100644 --- a/cpan/Scalar-List-Utils/t/dualvar.t +++ b/cpan/Scalar-List-Utils/t/dualvar.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Scalar::Util (); use Test::More (grep { /dualvar/ } @Scalar::Util::EXPORT_FAIL) @@ -22,13 +12,14 @@ use Config; Scalar::Util->import('dualvar'); Scalar::Util->import('isdual'); +my $var; $var = dualvar( 2.2,"string"); ok( isdual($var), 'Is a dualvar'); ok( $var == 2.2, 'Numeric value'); ok( $var eq "string", 'String value'); -$var2 = $var; +my $var2 = $var; ok( isdual($var2), 'Is a dualvar'); ok( $var2 == 2.2, 'copy Numeric value'); diff --git a/cpan/Scalar-List-Utils/t/first.t b/cpan/Scalar-List-Utils/t/first.t index 497cdd5188..ba7726ae56 100644 --- a/cpan/Scalar-List-Utils/t/first.t +++ b/cpan/Scalar-List-Utils/t/first.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use List::Util qw(first); use Test::More; @@ -68,7 +58,11 @@ like($@, qr/^Can't undef active subroutine/, "undef active sub"); # redefinition takes effect immediately depends on whether we're # running the Perl or XS implementation. -sub self_updating { local $^W; *self_updating = sub{1} ;1} +sub self_updating { + no warnings 'redefine'; + *self_updating = sub{1}; + 1 +} eval { $v = first \&self_updating, 1,2; }; is($@, '', 'redefine self'); diff --git a/cpan/Scalar-List-Utils/t/getmagic-once.t b/cpan/Scalar-List-Utils/t/getmagic-once.t index 00b3490783..431033cce8 100644 --- a/cpan/Scalar-List-Utils/t/getmagic-once.t +++ b/cpan/Scalar-List-Utils/t/getmagic-once.t @@ -1,18 +1,8 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} use strict; +use warnings; + use Scalar::Util qw(blessed reftype refaddr); use Test::More tests => 6; diff --git a/cpan/Scalar-List-Utils/t/isvstring.t b/cpan/Scalar-List-Utils/t/isvstring.t index 860113e067..9d345aa26f 100644 --- a/cpan/Scalar-List-Utils/t/isvstring.t +++ b/cpan/Scalar-List-Utils/t/isvstring.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; $|=1; use Scalar::Util (); @@ -21,12 +11,12 @@ use Test::More (grep { /isvstring/ } @Scalar::Util::EXPORT_FAIL) Scalar::Util->import(qw[isvstring]); -$vs = ord("A") == 193 ? 241.75.240 : 49.46.48; +my $vs = ord("A") == 193 ? 241.75.240 : 49.46.48; ok( $vs == "1.0", 'dotted num'); ok( isvstring($vs), 'isvstring'); -$sv = "1.0"; +my $sv = "1.0"; ok( !isvstring($sv), 'not isvstring'); diff --git a/cpan/Scalar-List-Utils/t/lln.t b/cpan/Scalar-List-Utils/t/lln.t index 1499cdb49d..df9ea3aea9 100644 --- a/cpan/Scalar-List-Utils/t/lln.t +++ b/cpan/Scalar-List-Utils/t/lln.t @@ -1,19 +1,8 @@ -#!/usr/bin/perl -w - -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +#!./perl use strict; +use warnings; + use Test::More tests => 19; use Scalar::Util qw(looks_like_number); diff --git a/cpan/Scalar-List-Utils/t/max.t b/cpan/Scalar-List-Utils/t/max.t index f12e00c0bb..adb222b1b0 100644 --- a/cpan/Scalar-List-Utils/t/max.t +++ b/cpan/Scalar-List-Utils/t/max.t @@ -1,19 +1,8 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - use strict; +use warnings; + use Test::More tests => 10; use List::Util qw(max); diff --git a/cpan/Scalar-List-Utils/t/maxstr.t b/cpan/Scalar-List-Utils/t/maxstr.t index 11d98ff558..ac135a1755 100644 --- a/cpan/Scalar-List-Utils/t/maxstr.t +++ b/cpan/Scalar-List-Utils/t/maxstr.t @@ -1,19 +1,8 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - use strict; +use warnings; + use Test::More tests => 5; use List::Util qw(maxstr); diff --git a/cpan/Scalar-List-Utils/t/min.t b/cpan/Scalar-List-Utils/t/min.t index 795fdca001..a7dfb10683 100644 --- a/cpan/Scalar-List-Utils/t/min.t +++ b/cpan/Scalar-List-Utils/t/min.t @@ -1,19 +1,8 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - use strict; +use warnings; + use Test::More tests => 10; use List::Util qw(min); diff --git a/cpan/Scalar-List-Utils/t/minstr.t b/cpan/Scalar-List-Utils/t/minstr.t index 021b309dad..ee6f2b7297 100644 --- a/cpan/Scalar-List-Utils/t/minstr.t +++ b/cpan/Scalar-List-Utils/t/minstr.t @@ -1,19 +1,8 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - use strict; +use warnings; + use Test::More tests => 5; use List::Util qw(minstr); diff --git a/cpan/Scalar-List-Utils/t/multicall-refcount.t b/cpan/Scalar-List-Utils/t/multicall-refcount.t deleted file mode 100644 index 1d6fb59808..0000000000 --- a/cpan/Scalar-List-Utils/t/multicall-refcount.t +++ /dev/null @@ -1,21 +0,0 @@ -use Test::More tests => 1; - -use List::Util 'first'; - -our $comparison; - -sub foo { - if( $comparison ) { - return 1; - } - else { - local $comparison = 1; - first \&foo, 1,2,3; - } -} - -for(1,2){ - foo(); -} - -ok( "Didn't crash calling recursively" ); diff --git a/cpan/Scalar-List-Utils/t/openhan.t b/cpan/Scalar-List-Utils/t/openhan.t index e0dffb6f53..89bdba4006 100644 --- a/cpan/Scalar-List-Utils/t/openhan.t +++ b/cpan/Scalar-List-Utils/t/openhan.t @@ -1,19 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - use strict; +use warnings; use Test::More tests => 21; use Scalar::Util qw(openhandle); diff --git a/cpan/Scalar-List-Utils/t/pair.t b/cpan/Scalar-List-Utils/t/pair.t index 46e05342ac..fab05dd158 100644 --- a/cpan/Scalar-List-Utils/t/pair.t +++ b/cpan/Scalar-List-Utils/t/pair.t @@ -1,7 +1,9 @@ #!./perl use strict; -use Test::More tests => 20; +use warnings; + +use Test::More tests => 23; use List::Util qw(pairgrep pairfirst pairmap pairs pairkeys pairvalues); no warnings 'misc'; # avoid "Odd number of elements" warnings most of the time @@ -88,6 +90,12 @@ is_deeply( [ pairs one => 1, two => ], [ [ one => 1 ], [ two => undef ] ], 'pairs pads with undef' ); +{ + my @p = pairs one => 1, two => 2; + is( $p[0]->key, "one", 'pairs ->key' ); + is( $p[0]->value, 1, 'pairs ->value' ); +} + is_deeply( [ pairkeys one => 1, two => 2 ], [qw( one two )], 'pairkeys' ); @@ -95,3 +103,15 @@ is_deeply( [ pairkeys one => 1, two => 2 ], is_deeply( [ pairvalues one => 1, two => 2 ], [ 1, 2 ], 'pairvalues' ); + +# pairmap within pairmap +{ + my @kvlist = ( + o1 => [ iA => 'A', iB => 'B' ], + o2 => [ iC => 'C', iD => 'D' ], + ); + + is_deeply( [ pairmap { pairmap { $b } @$b } @kvlist ], + [ 'A', 'B', 'C', 'D', ], + 'pairmap within pairmap' ); +} diff --git a/cpan/Scalar-List-Utils/t/product.t b/cpan/Scalar-List-Utils/t/product.t index 9f1aa56fc6..c397f828c6 100644 --- a/cpan/Scalar-List-Utils/t/product.t +++ b/cpan/Scalar-List-Utils/t/product.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Test::More tests => 13; @@ -88,7 +78,7 @@ is($v, $v1 * 42 * 2, 'bigint + builtin int'); { my $e1 = example->new(7, "test"); - $t = product($e1, 7, 7); + my $t = product($e1, 7, 7); is($t, 343, 'overload returning non-overload'); $t = product(8, $e1, 8); is($t, 448, 'overload returning non-overload'); diff --git a/cpan/Scalar-List-Utils/t/proto.t b/cpan/Scalar-List-Utils/t/proto.t index 50e401b59e..e9b653a666 100644 --- a/cpan/Scalar-List-Utils/t/proto.t +++ b/cpan/Scalar-List-Utils/t/proto.t @@ -1,29 +1,19 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Scalar::Util (); use Test::More (grep { /set_prototype/ } @Scalar::Util::EXPORT_FAIL) ? (skip_all => 'set_prototype requires XS version') - : (tests => 13); + : (tests => 14); Scalar::Util->import('set_prototype'); sub f { } is( prototype('f'), undef, 'no prototype'); -$r = set_prototype(\&f,'$'); +my $r = set_prototype(\&f,'$'); is( prototype('f'), '$', 'set prototype'); is( $r, \&f, 'return value'); @@ -57,3 +47,24 @@ ok($@ =~ /^set_prototype: not a reference/, 'not a reference'); eval { &set_prototype( \'f', '' ); }; ok($@ =~ /^set_prototype: not a subroutine reference/, 'not a sub reference'); + +# RT 72080 + +{ + package TiedCV; + sub TIESCALAR { + my $class = shift; + return bless {@_}, $class; + } + sub FETCH { + return \&my_subr; + } + sub my_subr { + } +} + +my $cv; +tie $cv, 'TiedCV'; + +&Scalar::Util::set_prototype($cv, '$$'); +is( prototype($cv), '$$', 'set_prototype() on tied CV ref' ); diff --git a/cpan/Scalar-List-Utils/t/readonly.t b/cpan/Scalar-List-Utils/t/readonly.t index 91385fd18f..c8e19ff4c8 100644 --- a/cpan/Scalar-List-Utils/t/readonly.t +++ b/cpan/Scalar-List-Utils/t/readonly.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Scalar::Util qw(readonly); use Test::More tests => 11; diff --git a/cpan/Scalar-List-Utils/t/reduce.t b/cpan/Scalar-List-Utils/t/reduce.t index 4468ab8611..b8acbe7c57 100644 --- a/cpan/Scalar-List-Utils/t/reduce.t +++ b/cpan/Scalar-List-Utils/t/reduce.t @@ -1,18 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - +use strict; +use warnings; use List::Util qw(reduce min); use Test::More; @@ -28,7 +17,7 @@ is( $v, 9, '4-arg divide'); $v = reduce { $a / $b } 6; is( $v, 6, 'one arg'); -@a = map { rand } 0 .. 20; +my @a = map { rand } 0 .. 20; $v = reduce { $a < $b ? $a : $b } @a; is( $v, min(@a), 'min'); @@ -95,7 +84,11 @@ like($@, qr/^Can't undef active subroutine/, "undef active sub"); # redefinition takes effect immediately depends on whether we're # running the Perl or XS implementation. -sub self_updating { local $^W; *self_updating = sub{1} ;1 } +sub self_updating { + no warnings 'redefine'; + *self_updating = sub{1}; + 1 +} eval { $v = reduce \&self_updating, 1,2; }; is($@, '', 'redefine self'); diff --git a/cpan/Scalar-List-Utils/t/refaddr.t b/cpan/Scalar-List-Utils/t/refaddr.t index cc93834aa4..c208943fcf 100644 --- a/cpan/Scalar-List-Utils/t/refaddr.t +++ b/cpan/Scalar-List-Utils/t/refaddr.t @@ -1,34 +1,24 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} - +use strict; +use warnings; use Test::More tests => 32; use Scalar::Util qw(refaddr); -use vars qw($t $y $x *F $v $r); +use vars qw(*F); use Symbol qw(gensym); # Ensure we do not trigger and tied methods tie *F, 'MyTie'; my $i = 1; -foreach $v (undef, 10, 'string') { +foreach my $v (undef, 10, 'string') { is(refaddr($v), undef, "not " . (defined($v) ? "'$v'" : "undef")); } -foreach $r ({}, \$t, [], \*F, sub {}) { +my $t; +foreach my $r ({}, \$t, [], \*F, sub {}) { my $n = "$r"; $n =~ /0x(\w+)/; my $addr = do { local $^W; hex $1 }; @@ -61,7 +51,10 @@ foreach $r ({}, \$t, [], \*F, sub {}) { { my $z = bless {}, '0'; ok(refaddr($z)); - @{"0::ISA"} = qw(FooBar); + { + no strict 'refs'; + @{"0::ISA"} = qw(FooBar); + } my $a = {}; my $r = refaddr($a); $z = bless $a, '0'; @@ -81,6 +74,7 @@ sub TIEHANDLE { bless {} } sub DESTROY {} sub AUTOLOAD { + our $AUTOLOAD; warn "$AUTOLOAD called"; exit 1; # May be in an eval } diff --git a/cpan/Scalar-List-Utils/t/reftype.t b/cpan/Scalar-List-Utils/t/reftype.t index 31a5d3b841..a40e41493b 100644 --- a/cpan/Scalar-List-Utils/t/reftype.t +++ b/cpan/Scalar-List-Utils/t/reftype.t @@ -1,22 +1,12 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Test::More tests => 32; use Scalar::Util qw(reftype); -use vars qw($t $y $x *F); +use vars qw(*F); use Symbol qw(gensym); # Ensure we do not trigger and tied methods @@ -26,7 +16,8 @@ my $RE = $] < 5.011 ? 'SCALAR' : 'REGEXP'; my $s = []; # SvTYPE($s) is SVt_RV, and SvROK($s) is true $s = undef; # SvTYPE($s) is SVt_RV, but SvROK($s) is false -@test = ( +my $t; +my @test = ( [ undef, 1, 'number' ], [ undef, 'A', 'string' ], [ HASH => {}, 'HASH ref' ], @@ -41,7 +32,7 @@ $s = undef; # SvTYPE($s) is SVt_RV, but SvROK($s) is false [ $RE => qr/x/, 'REGEEXP' ], ); -foreach $test (@test) { +foreach my $test (@test) { my($type,$what, $n) = @$test; is( reftype($what), $type, $n); @@ -60,6 +51,7 @@ sub TIEHANDLE { bless {} } sub DESTROY {} sub AUTOLOAD { + our $AUTOLOAD; warn "$AUTOLOAD called"; exit 1; # May be in an eval } diff --git a/cpan/Scalar-List-Utils/t/shuffle.t b/cpan/Scalar-List-Utils/t/shuffle.t index d3fbd6cd1f..dff963715d 100644 --- a/cpan/Scalar-List-Utils/t/shuffle.t +++ b/cpan/Scalar-List-Utils/t/shuffle.t @@ -1,17 +1,7 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; use Test::More tests => 6; diff --git a/cpan/Scalar-List-Utils/t/stack-corruption.t b/cpan/Scalar-List-Utils/t/stack-corruption.t index dff5af03c4..03f141af68 100644 --- a/cpan/Scalar-List-Utils/t/stack-corruption.t +++ b/cpan/Scalar-List-Utils/t/stack-corruption.t @@ -1,22 +1,15 @@ #!./perl BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } if ($] eq "5.008009" or $] eq "5.010000" or $] le "5.006002") { print "1..0 # Skip: known to fail on $]\n"; exit 0; } } +use strict; +use warnings; + use List::Util qw(reduce); use Test::More tests => 1; diff --git a/cpan/Scalar-List-Utils/t/sum.t b/cpan/Scalar-List-Utils/t/sum.t index a0e5c1e588..7a12813ff0 100644 --- a/cpan/Scalar-List-Utils/t/sum.t +++ b/cpan/Scalar-List-Utils/t/sum.t @@ -1,20 +1,11 @@ #!./perl -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} +use strict; +use warnings; -use Test::More tests => 13; +use Test::More tests => 15; +use Config; use List::Util qw(sum); my $v = sum; @@ -37,6 +28,9 @@ is( $v, 0, 'variable arg'); $v = sum(-3.5,3); is( $v, -0.5, 'real numbers'); +$v = sum(3,-3.5); +is( $v, -0.5, 'initial integer, then real'); + my $one = Foo->new(1); my $two = Foo->new(2); my $thr = Foo->new(3); @@ -88,10 +82,18 @@ is($v, $v1 + 42 + 2, 'bigint + builtin int'); { my $e1 = example->new(7, "test"); - $t = sum($e1, 7, 7); + my $t = sum($e1, 7, 7); is($t, 21, 'overload returning non-overload'); $t = sum(8, $e1, 8); is($t, 23, 'overload returning non-overload'); $t = sum(9, 9, $e1); is($t, 25, 'overload returning non-overload'); } + +SKIP: { + skip "IV is not at least 64bit", 1 unless $Config{ivsize} >= 8; + + # Sum using NV will only preserve 53 bits of integer precision + my $t = sum(1<<60, 1); + cmp_ok($t, '>', 1<<60, 'sum uses IV where it can'); +} diff --git a/cpan/Scalar-List-Utils/t/sum0.t b/cpan/Scalar-List-Utils/t/sum0.t index e76f8a79d3..6b0874174f 100644 --- a/cpan/Scalar-List-Utils/t/sum0.t +++ b/cpan/Scalar-List-Utils/t/sum0.t @@ -1,3 +1,5 @@ +#!./perl + use strict; use warnings; diff --git a/cpan/Scalar-List-Utils/t/tainted.t b/cpan/Scalar-List-Utils/t/tainted.t index 8666117fe4..e483dfd06c 100644 --- a/cpan/Scalar-List-Utils/t/tainted.t +++ b/cpan/Scalar-List-Utils/t/tainted.t @@ -1,20 +1,7 @@ #!./perl -T -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - require Config; import Config; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } - elsif(!grep {/blib/} @INC) { - unshift(@INC, qw(./inc ./blib/arch ./blib/lib)); - } -} +use strict; +use warnings; use Test::More tests => 5; diff --git a/cpan/Scalar-List-Utils/t/weak.t b/cpan/Scalar-List-Utils/t/weak.t index 842f3f8662..86ded9794f 100644 --- a/cpan/Scalar-List-Utils/t/weak.t +++ b/cpan/Scalar-List-Utils/t/weak.t @@ -1,18 +1,9 @@ #!./perl use strict; +use warnings; + use Config; -BEGIN { - unless (-d 'blib') { - chdir 't' if -d 't'; - @INC = '../lib'; - keys %Config; # Silence warning - if ($Config{extensions} !~ /\bList\/Util\b/) { - print "1..0 # Skip: List::Util was not built\n"; - exit 0; - } - } -} use Scalar::Util (); use Test::More ((grep { /weaken/ } @Scalar::Util::EXPORT_FAIL) and !$ENV{PERL_CORE}) |