Hello community,

here is the log from the commit of package perl-Scalar-List-Utils for 
openSUSE:Factory checked in at 2016-04-12 19:33:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Scalar-List-Utils (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Scalar-List-Utils.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Scalar-List-Utils"

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/perl-Scalar-List-Utils/perl-Scalar-List-Utils.changes
    2016-03-26 15:27:37.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.perl-Scalar-List-Utils.new/perl-Scalar-List-Utils.changes
       2016-04-12 19:33:55.000000000 +0200
@@ -1,0 +2,16 @@
+Mon Apr  4 10:21:07 UTC 2016 - [email protected]
+
+- updated to 1.45
+   see /usr/share/doc/packages/perl-Scalar-List-Utils/Changes
+
+  1.45 -- 2016/03/25 16:09:40
+       [CHANGES]
+        * Renamed existing uniq() to uniqstr()
+        * Canonicalise undef to {empty string,zero} in uniq{str,num}()
+        * Add a new uniq() with more DWIMish semantics around undef
+  
+       [BUGFIXES]
+        * Fix uses of GET magic by the uniq*() family of functions. GET magic
+          is now always invoked exactly once if it exists.
+
+-------------------------------------------------------------------

Old:
----
  Scalar-List-Utils-1.44.tar.gz

New:
----
  Scalar-List-Utils-1.45.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Scalar-List-Utils.spec ++++++
--- /var/tmp/diff_new_pack.lKx4tA/_old  2016-04-12 19:33:55.000000000 +0200
+++ /var/tmp/diff_new_pack.lKx4tA/_new  2016-04-12 19:33:55.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Scalar-List-Utils
-Version:        1.44
+Version:        1.45
 Release:        0
 %define cpan_name Scalar-List-Utils
 Summary:        Common Scalar and List utility subroutines

++++++ Scalar-List-Utils-1.44.tar.gz -> Scalar-List-Utils-1.45.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/Changes 
new/Scalar-List-Utils-1.45/Changes
--- old/Scalar-List-Utils-1.44/Changes  2016-03-18 00:09:46.000000000 +0100
+++ new/Scalar-List-Utils-1.45/Changes  2016-03-25 17:09:57.000000000 +0100
@@ -1,3 +1,13 @@
+1.45 -- 2016/03/25 16:09:40
+       [CHANGES]
+        * Renamed existing uniq() to uniqstr()
+        * Canonicalise undef to {empty string,zero} in uniq{str,num}()
+        * Add a new uniq() with more DWIMish semantics around undef
+
+       [BUGFIXES]
+        * Fix uses of GET magic by the uniq*() family of functions. GET magic
+          is now always invoked exactly once if it exists.
+
 1.44 -- 2016/03/17 23:08:46
        [CHANGES]
         * Added List::Util::uniq() and uniqnum()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/ListUtil.xs 
new/Scalar-List-Utils-1.45/ListUtil.xs
--- old/Scalar-List-Utils-1.44/ListUtil.xs      2016-03-18 00:07:44.000000000 
+0100
+++ new/Scalar-List-Utils-1.45/ListUtil.xs      2016-03-23 19:20:15.000000000 
+0100
@@ -1011,8 +1011,9 @@
 uniq(...)
 PROTOTYPE: @
 ALIAS:
-    uniq    = 0
-    uniqnum = 1
+    uniqnum = 0
+    uniqstr = 1
+    uniq    = 2
 CODE:
 {
     int retcount = 0;
@@ -1020,28 +1021,33 @@
     SV **args = &PL_stack_base[ax];
     HV *seen;
 
-    if(items < 2) {
+    if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
+        /* Optimise for the case of the empty list or a defined nonmagic
+         * singleton. Leave a singleton magical||undef for the regular case */
         retcount = items;
         goto finish;
     }
 
     sv_2mortal((SV *)(seen = newHV()));
 
-    if(ix) {
+    if(ix == 0) {
+        /* uniqnum */
         /* A temporary buffer for number stringification */
         SV *keysv = sv_newmortal();
 
         for(index = 0 ; index < items ; index++) {
             SV *arg = args[index];
 
-            SvGETMAGIC(arg);
+            if(SvGAMAGIC(arg))
+                /* clone the value so we don't invoke magic again */
+                arg = sv_mortalcopy(arg);
 
             if(SvUOK(arg))
-                sv_setpvf(keysv, "%"UVuf, SvUV_nomg(arg));
+                sv_setpvf(keysv, "%"UVuf, SvUV(arg));
             else if(SvIOK(arg))
-                sv_setpvf(keysv, "%"IVdf, SvIV_nomg(arg));
+                sv_setpvf(keysv, "%"IVdf, SvIV(arg));
             else
-                sv_setpvf(keysv, "%"NVgf, SvNV_nomg(arg));
+                sv_setpvf(keysv, "%"NVgf, SvNV(arg));
 #ifdef HV_FETCH_EMPTY_HE
             HE* he = hv_common(seen, NULL, SvPVX(keysv), SvCUR(keysv), 0, 
HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
             if (HeVAL(he))
@@ -1056,29 +1062,51 @@
 #endif
 
             if(GIMME_V == G_ARRAY)
-                ST(retcount) = arg;
+                ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSViv(0));
             retcount++;
         }
     }
-    else
+    else {
+        /* uniqstr or uniq */
+        int seen_undef = 0;
+
         for(index = 0 ; index < items ; index++) {
+            SV *arg = args[index];
+
+            if(SvGAMAGIC(arg))
+                /* clone the value so we don't invoke magic again */
+                arg = sv_mortalcopy(arg);
+
+            if(ix == 2 && !SvOK(arg)) {
+                /* special handling of undef for uniq() */
+                if(seen_undef)
+                    continue;
+
+                seen_undef++;
+
+                if(GIMME_V == G_ARRAY)
+                    ST(retcount) = arg;
+                retcount++;
+                continue;
+            }
 #ifdef HV_FETCH_EMPTY_HE
-            HE* he = hv_common(seen, args[index], NULL, 0, 0, HV_FETCH_LVALUE 
| HV_FETCH_EMPTY_HE, NULL, 0);
+            HE* he = hv_common(seen, arg, NULL, 0, 0, HV_FETCH_LVALUE | 
HV_FETCH_EMPTY_HE, NULL, 0);
             if (HeVAL(he))
                 continue;
 
             HeVAL(he) = &PL_sv_undef;
 #else
-            if (hv_exists_ent(seen, args[index], 0))
+            if (hv_exists_ent(seen, arg, 0))
                 continue;
 
-            hv_store_ent(seen, args[index], &PL_sv_undef, 0);
+            hv_store_ent(seen, arg, &PL_sv_undef, 0);
 #endif
 
             if(GIMME_V == G_ARRAY)
-                ST(retcount) = args[index];
+                ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSVpvn("", 0));
             retcount++;
         }
+    }
 
   finish:
     if(GIMME_V == G_ARRAY)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/META.json 
new/Scalar-List-Utils-1.45/META.json
--- old/Scalar-List-Utils-1.44/META.json        2016-03-18 00:10:20.000000000 
+0100
+++ new/Scalar-List-Utils-1.45/META.json        2016-03-25 17:14:35.000000000 
+0100
@@ -49,6 +49,6 @@
          "web" : "https://github.com/Scalar-List-Utils/Scalar-List-Utils";
       }
    },
-   "version" : "1.44",
+   "version" : "1.45",
    "x_serialization_backend" : "JSON::PP version 2.27300"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/META.yml 
new/Scalar-List-Utils-1.45/META.yml
--- old/Scalar-List-Utils-1.44/META.yml 2016-03-18 00:10:20.000000000 +0100
+++ new/Scalar-List-Utils-1.45/META.yml 2016-03-25 17:14:35.000000000 +0100
@@ -23,5 +23,5 @@
 resources:
   bugtracker: 
https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils
   repository: https://github.com/Scalar-List-Utils/Scalar-List-Utils.git
-version: '1.44'
+version: '1.45'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/lib/List/Util/XS.pm 
new/Scalar-List-Utils-1.45/lib/List/Util/XS.pm
--- old/Scalar-List-Utils-1.44/lib/List/Util/XS.pm      2016-03-18 
00:09:51.000000000 +0100
+++ new/Scalar-List-Utils-1.45/lib/List/Util/XS.pm      2016-03-25 
17:14:00.000000000 +0100
@@ -3,7 +3,7 @@
 use warnings;
 use List::Util;
 
-our $VERSION = "1.44";       # FIXUP
+our $VERSION = "1.45";       # FIXUP
 $VERSION = eval $VERSION;    # FIXUP
 
 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/lib/List/Util.pm 
new/Scalar-List-Utils-1.45/lib/List/Util.pm
--- old/Scalar-List-Utils-1.44/lib/List/Util.pm 2016-03-18 00:09:51.000000000 
+0100
+++ new/Scalar-List-Utils-1.45/lib/List/Util.pm 2016-03-25 17:14:00.000000000 
+0100
@@ -12,10 +12,10 @@
 
 our @ISA        = qw(Exporter);
 our @EXPORT_OK  = qw(
-  all any first min max minstr maxstr none notall product reduce sum sum0 
shuffle uniq uniqnum
+  all any first min max minstr maxstr none notall product reduce sum sum0 
shuffle uniq uniqnum uniqstr
   pairs unpairs pairkeys pairvalues pairmap pairgrep pairfirst
 );
-our $VERSION    = "1.44";
+our $VERSION    = "1.45";
 our $XS_VERSION = $VERSION;
 $VERSION    = eval $VERSION;
 
@@ -52,7 +52,7 @@
 
       pairs pairkeys pairvalues pairfirst pairgrep pairmap
 
-      shuffle
+      shuffle uniqnum uniqstr
     );
 
 =head1 DESCRIPTION
@@ -114,6 +114,20 @@
 
   $foo = reduce { $a + $b } 0, @values;             # sum with 0 identity value
 
+The above example code blocks also suggest how to use C<reduce> to build a
+more efficient combined version of one of these basic functions and a C<map>
+block. For example, to find the total length of the all the strings in a list,
+we could use
+
+    $total = sum map { length } @strings;
+
+However, this produces a list of temporary integer values as long as the
+original list of strings, only to reduce it down to a single value again. We
+can compute the same result more efficiently by using C<reduce> with a code
+block that accumulates lengths by writing this instead as:
+
+    $total = reduce { $a + length $b } 0, @strings
+
 The remaining list-reduction functions are all specialisations of this generic
 idea.
 
@@ -466,31 +480,64 @@
 
     my @subset = uniq @values
 
+I<Since version 1.45.>
+
 Filters a list of values to remove subsequent duplicates, as judged by a
-string equality test. Preserves the order of unique elements, and retains the
-first value of any duplicate set.
+DWIM-ish string equality or C<undef> test. Preserves the order of unique
+elements, and retains the first value of any duplicate set.
 
     my $count = uniq @values
 
 In scalar context, returns the number of elements that would have been
 returned as a list.
 
-Note that C<undef> is not handled specially; it is treated the same as most
-other perl operations that work on strings. That is, C<undef> behaves
-identically to the empty string, but in addition a warning is produced.
+The C<undef> value is treated by this function as distinct from the empty
+string, and no warning will be produced. It is left as-is in the returned
+list. Subsequent C<undef> values are still considered identical to the first,
+and will be removed.
 
 =head2 uniqnum
 
     my @subset = uniqnum @values
 
-Filters a list of values similarly to L</uniq>, but judges duplicates
-numerically instead.
+I<Since version 1.44.>
+
+Filters a list of values to remove subsequent duplicates, as judged by a
+numerical equality test. Preserves the order of unique elements, and retains
+the first value of any duplicate set.
 
     my $count = uniqnum @values
 
 In scalar context, returns the number of elements that would have been
 returned as a list.
 
+Note that C<undef> is treated much as other numerical operations treat it; it
+compares equal to zero but additionally produces a warning if such warnings
+are enabled (C<use warnings 'uninitialized';>). In addition, an C<undef> in
+the returned list is coerced into a numerical zero, so that the entire list of
+values returned by C<uniqnum> are well-behaved as numbers.
+
+=head2 uniqstr
+
+    my @subset = uniqstr @values
+
+I<Since version 1.45.>
+
+Filters a list of values to remove subsequent duplicates, as judged by a
+string equality test. Preserves the order of unique elements, and retains the
+first value of any duplicate set.
+
+    my $count = uniqstr @values
+
+In scalar context, returns the number of elements that would have been
+returned as a list.
+
+Note that C<undef> is treated much as other string operations treat it; it
+compares equal to the empty string but additionally produces a warning if such
+warnings are enabled (C<use warnings 'uninitialized';>). In addition, an
+C<undef> in the returned list is coerced into an empty string, so that the
+entire list of values returned by C<uniqstr> are well-behaved as strings.
+
 =cut
 
 =head1 KNOWN BUGS
@@ -550,17 +597,9 @@
  say for uniqnum( $x, $y );
 
 Will print just the value of C<$x>, believing that C<$y> is a numerically-
-equivalent value. This bug does not affect C<uniq()>, which will correctly
+equivalent value. This bug does not affect C<uniqstr()>, which will correctly
 observe that the two values stringify to different strings.
 
-=head2 uniqnum() invokes GET magic multiple times before perl 5.14
-
-Perl versions before 5.14 lack the C<SvNV_nomg()> and related macros. On these
-older versions, C<uniqnum()> will invoke GET magic twice on each argument
-passed in. This ought not cause any major problems other than a slight
-performance penalty, because well-designed GET magic should be idempotent.
-This does not affect C<uniq()>, nor builds for perl 5.14 or later.
-
 =head1 SUGGESTED ADDITIONS
 
 The following are additions that have been requested, but I have been reluctant
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/lib/Scalar/Util.pm 
new/Scalar-List-Utils-1.45/lib/Scalar/Util.pm
--- old/Scalar-List-Utils-1.44/lib/Scalar/Util.pm       2016-03-18 
00:09:51.000000000 +0100
+++ new/Scalar-List-Utils-1.45/lib/Scalar/Util.pm       2016-03-25 
17:14:00.000000000 +0100
@@ -17,7 +17,7 @@
   dualvar isdual isvstring looks_like_number openhandle readonly set_prototype
   tainted
 );
-our $VERSION    = "1.44";
+our $VERSION    = "1.45";
 $VERSION   = eval $VERSION;
 
 require List::Util; # List::Util loads the XS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/lib/Sub/Util.pm 
new/Scalar-List-Utils-1.45/lib/Sub/Util.pm
--- old/Scalar-List-Utils-1.44/lib/Sub/Util.pm  2016-03-18 00:09:51.000000000 
+0100
+++ new/Scalar-List-Utils-1.45/lib/Sub/Util.pm  2016-03-25 17:14:00.000000000 
+0100
@@ -15,7 +15,7 @@
   subname set_subname
 );
 
-our $VERSION    = "1.44";
+our $VERSION    = "1.45";
 $VERSION   = eval $VERSION;
 
 require List::Util; # as it has the XS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scalar-List-Utils-1.44/t/uniq.t 
new/Scalar-List-Utils-1.45/t/uniq.t
--- old/Scalar-List-Utils-1.44/t/uniq.t 2016-03-18 00:09:51.000000000 +0100
+++ new/Scalar-List-Utils-1.45/t/uniq.t 2016-03-25 17:14:00.000000000 +0100
@@ -3,28 +3,45 @@
 use strict;
 use warnings;
 
-use Test::More tests => 19;
-use List::Util qw( uniq uniqnum );
+use Test::More tests => 30;
+use List::Util qw( uniqnum uniqstr uniq );
 
-is_deeply( [ uniq ],
+use Tie::Array;
+
+is_deeply( [ uniqstr ],
            [],
-           'uniq of empty list' );
+           'uniqstr of empty list' );
 
-is_deeply( [ uniq qw( abc ) ],
+is_deeply( [ uniqstr qw( abc ) ],
            [qw( abc )],
-           'uniq of singleton list' );
+           'uniqstr of singleton list' );
 
-is_deeply( [ uniq qw( x x x ) ],
+is_deeply( [ uniqstr qw( x x x ) ],
            [qw( x )],
-           'uniq of repeated-element list' );
+           'uniqstr of repeated-element list' );
 
-is_deeply( [ uniq qw( a b a c ) ],
+is_deeply( [ uniqstr qw( a b a c ) ],
            [qw( a b c )],
-           'uniq removes subsequent duplicates' );
+           'uniqstr removes subsequent duplicates' );
 
-is_deeply( [ uniq qw( 1 1.0 1E0 ) ],
+is_deeply( [ uniqstr qw( 1 1.0 1E0 ) ],
            [qw( 1 1.0 1E0 )],
-           'uniq compares strings' );
+           'uniqstr compares strings' );
+
+{
+    my $warnings = "";
+    local $SIG{__WARN__} = sub { $warnings .= join "", @_ };
+
+    is_deeply( [ uniqstr "", undef ],
+               [ "" ],
+               'uniqstr considers undef and empty-string equivalent' );
+
+    ok( length $warnings, 'uniqstr on undef yields a warning' );
+
+    is_deeply( [ uniqstr undef ],
+               [ "" ],
+               'uniqstr on undef coerces to empty-string' );
+}
 
 {
     my $warnings = "";
@@ -32,15 +49,15 @@
 
     my $cafe = "cafe\x{301}";
 
-    is_deeply( [ uniq $cafe ],
+    is_deeply( [ uniqstr $cafe ],
                [ $cafe ],
-               'uniq is happy with Unicode strings' );
+               'uniqstr is happy with Unicode strings' );
 
     utf8::encode( my $cafebytes = $cafe );
 
-    is_deeply( [ uniq $cafe, $cafebytes ],
+    is_deeply( [ uniqstr $cafe, $cafebytes ],
                [ $cafe, $cafebytes ],
-               'uniq does not squash bytewise-equal but differently-encoded 
strings' );
+               'uniqstr does not squash bytewise-equal but differently-encoded 
strings' );
 
     is( $warnings, "", 'No warnings are printed when handling Unicode strings' 
);
 }
@@ -70,7 +87,41 @@
                'uniqnum preserves uniqness of full integer range' );
 }
 
-is( scalar( uniq qw( a b c d a b e ) ), 5, 'uniq() in scalar context' );
+{
+    my $warnings = "";
+    local $SIG{__WARN__} = sub { $warnings .= join "", @_ };
+
+    is_deeply( [ uniqnum 0, undef ],
+               [ 0 ],
+               'uniqnum considers undef and zero equivalent' );
+
+    ok( length $warnings, 'uniqnum on undef yields a warning' );
+
+    is_deeply( [ uniqnum undef ],
+               [ 0 ],
+               'uniqnum on undef coerces to zero' );
+}
+
+is_deeply( [ uniq () ],
+           [],
+           'uniq of empty list' );
+
+{
+    my $warnings = "";
+    local $SIG{__WARN__} = sub { $warnings .= join "", @_ };
+
+    is_deeply( [ uniq "", undef ],
+               [ "", undef ],
+               'uniq distintinguishes empty-string from undef' );
+
+    is_deeply( [ uniq undef, undef ],
+               [ undef ],
+               'uniq considers duplicate undefs as identical' );
+
+    ok( !length $warnings, 'uniq on undef does not warn' );
+}
+
+is( scalar( uniqstr qw( a b c d a b e ) ), 5, 'uniqstr() in scalar context' );
 
 {
     package Stringify;
@@ -83,9 +134,9 @@
 
     my @strs = map { Stringify->new( $_ ) } qw( foo foo bar );
 
-    is_deeply( [ uniq @strs ],
+    is_deeply( [ uniqstr @strs ],
                [ $strs[0], $strs[2] ],
-               'uniq respects stringify overload' );
+               'uniqstr respects stringify overload' );
 }
 
 {
@@ -122,25 +173,41 @@
     my @destroyed = (0) x 3;
     my @notifiers = map { DestroyNotifier->new( \$destroyed[$_] ) } 0 .. 2;
 
-    my @uniq = uniq @notifiers;
+    my @uniqstr = uniqstr @notifiers;
     undef @notifiers;
 
     is_deeply( \@destroyed, [ 0, 1, 1 ],
-               'values filtered by uniq() are destroyed' );
+               'values filtered by uniqstr() are destroyed' );
 
-    undef @uniq;
+    undef @uniqstr;
     is_deeply( \@destroyed, [ 1, 1, 1 ],
                'all values destroyed' );
 }
 
 {
     "a a b" =~ m/(.) (.) (.)/;
-    is_deeply( [ uniq $1, $2, $3 ],
+    is_deeply( [ uniqstr $1, $2, $3 ],
                [qw( a b )],
-               'uniq handles magic' );
+               'uniqstr handles magic' );
 
     "1 1 2" =~ m/(.) (.) (.)/;
     is_deeply( [ uniqnum $1, $2, $3 ],
                [ 1, 2 ],
                'uniqnum handles magic' );
 }
+
+{
+    my @array;
+    tie @array, 'Tie::StdArray';
+    @array = (
+        ( map { ( 1 .. 10 ) } 0 .. 1 ),
+        ( map { ( 'a' .. 'z' ) } 0 .. 1 )
+    );
+
+    my @u = uniq @array;
+    is_deeply(
+        \@u,
+        [ 1 .. 10, 'a' .. 'z' ],
+        'uniq uniquifies mixed numbers and strings correctly in a tied array'
+    );
+}


Reply via email to