In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/e2ec1b05ae07740bd4d51ac9fc407d6f104f7172?hp=b813f4458249da44eff5ac0843dc28de22112299>

- Log -----------------------------------------------------------------
commit e2ec1b05ae07740bd4d51ac9fc407d6f104f7172
Author: Aristotle Pagaltzis <[email protected]>
Date:   Thu Oct 10 07:24:10 2013 +0200

    perldata: document corrected list slicing behaviour

M       pod/perldata.pod

commit cbce292e0bfa19940c2aac7701c8ae7ca79366e5
Author: Father Chrysostomos <[email protected]>
Date:   Wed Dec 3 13:55:03 2014 -0800

    [perl #114498] lslice returning empty vs undef
    
    Formerly, list slice would return an empty list if all the indices
    fell outside the actual list, but would return ‘undef’ for every index
    specified if but one of them fell within the list.
    
    This was not implemented according to the original design, according
    to which list slice would give an empty list (for a non-zero number of
    indices) only if the list on the left-hand side were empty.
    
    This commit rectifies that.  See ticket #114498 for the discussion.

M       pp.c
M       t/op/list.t
-----------------------------------------------------------------------

Summary of changes:
 pod/perldata.pod | 25 ++++++++++---------------
 pp.c             |  7 +------
 t/op/list.t      | 29 ++++++++++++++++++-----------
 3 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/pod/perldata.pod b/pod/perldata.pod
index 436f135..5316fe2 100644
--- a/pod/perldata.pod
+++ b/pod/perldata.pod
@@ -917,26 +917,21 @@ values of the array or hash.
         s/(\w+)/\u\L$1/g;   # "titlecase" words
     }
 
-A slice of an empty list is still an empty list.  Thus:
+As a special exception, when you slice a list (but not an array or a hash),
+if the list evaluates to empty, then taking a slice of that empty list will
+always yield the empty list in turn.  Thus:
 
-    @a = ()[1,0];           # @a has no elements
-    @b = (@a)[0,1];         # @b has no elements
-
-But:
-
-    @a = (1)[1,0];          # @a has two elements
-    @b = (1,undef)[1,0,2];  # @b has three elements
-
-More generally, a slice yields the empty list if it indexes only
-beyond the end of a list:
-
-    @a = (1)[  1,2];        # @a has no elements
-    @b = (1)[0,1,2];        # @b has three elements
+    @a = ()[0,1];          # @a has no elements
+    @b = (@a)[0,1];        # @b has no elements
+    @c = (sub{}->())[0,1]; # @c has no elements
+    @d = ('a','b')[0,1];   # @d has two elements
+    @e = (@d)[0,1,8,9];    # @e has four elements
+    @f = (@d)[8,9];        # @f has two elements
 
 This makes it easy to write loops that terminate when a null list
 is returned:
 
-    while ( ($home, $user) = (getpwent)[7,0]) {
+    while ( ($home, $user) = (getpwent)[7,0] ) {
         printf "%-8s %s\n", $user, $home;
     }
 
diff --git a/pp.c b/pp.c
index 3ec401d..49798e2 100644
--- a/pp.c
+++ b/pp.c
@@ -4974,7 +4974,6 @@ PP(pp_lslice)
     SV ** const lastlelem = PL_stack_base + POPMARK;
     SV ** const firstlelem = PL_stack_base + POPMARK + 1;
     SV ** const firstrelem = lastlelem + 1;
-    I32 is_something_there = FALSE;
     const U8 mod = PL_op->op_flags & OPf_MOD;
 
     const I32 max = lastrelem - lastlelem;
@@ -5004,7 +5003,6 @@ PP(pp_lslice)
        if (ix < 0 || ix >= max)
            *lelem = &PL_sv_undef;
        else {
-           is_something_there = TRUE;
            if (!(*lelem = firstrelem[ix]))
                *lelem = &PL_sv_undef;
            else if (mod && SvPADTMP(*lelem)) {
@@ -5012,10 +5010,7 @@ PP(pp_lslice)
             }
        }
     }
-    if (is_something_there)
-       SP = lastlelem;
-    else
-       SP = firstlelem - 1;
+    SP = lastlelem;
     RETURN;
 }
 
diff --git a/t/op/list.t b/t/op/list.t
index d3f6b50..c7056d0 100644
--- a/t/op/list.t
+++ b/t/op/list.t
@@ -3,10 +3,10 @@
 BEGIN {
     chdir 't' if -d 't';
     @INC = qw(. ../lib);
+    require "./test.pl";
 }
 
-require "./test.pl";
-plan( tests => 67 );
+plan( tests => 69 );
 
 @foo = (1, 2, 3, 4);
 cmp_ok($foo[0], '==', 1, 'first elem');
@@ -146,21 +146,28 @@ cmp_ok(join('',(1,2),3,(4,5)),'eq','12345','list 
(..).(..)');
 
     my $size = scalar(()[1..1]);
     cmp_ok($size,'==','0','size nil');
+
+    $size = scalar(()=((1,2,3,4,5)[()])[2,3,4]);
+    is $size, 0, 'slice of empty list from complex expr is empty list';
+
+    @a = (1)[2,3,4];
+    is "@{[ map $_//'undef', @a ]}", "undef undef undef",
+       'slice beyond the end of non-empty list returns undefs';
 }
 
 {
     # perl #39882
-    sub test_zero_args {
+    sub test_two_args {
         my $test_name = shift;
-        is(scalar(@_), 0, $test_name);
+        is(scalar(@_), 2, $test_name);
     }
-    test_zero_args("simple list slice",      (10,11)[2,3]);
-    test_zero_args("grepped list slice",     grep(1, (10,11)[2,3]));
-    test_zero_args("sorted list slice",      sort((10,11)[2,3]));
-    test_zero_args("assigned list slice",    my @tmp = (10,11)[2,3]);
-    test_zero_args("do-returned list slice", do { (10,11)[2,3]; });
-    test_zero_args("list literal slice",     qw(a b)[2,3]);
-    test_zero_args("empty literal slice",    qw()[2,3]);
+    test_two_args("simple list slice",      (10,11)[2,3]);
+    test_two_args("grepped list slice",     grep(1, (10,11)[2,3]));
+    test_two_args("sorted list slice",      sort((10,11)[2,3]));
+    test_two_args("assigned list slice",    my @tmp = (10,11)[2,3]);
+    test_two_args("do-returned list slice", do { (10,11)[2,3]; });
+    test_two_args("list literal slice",     qw(a b)[2,3]);
+    is (()=qw()[2,3], 0, "empty literal slice");
 }
 
 {

--
Perl5 Master Repository

Reply via email to