summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-12-03 13:55:03 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-12-03 17:48:26 -0800
commitcbce292e0bfa19940c2aac7701c8ae7ca79366e5 (patch)
tree91bb9f7061c52d58b1376542dd58bf0474a9bb90
parentb813f4458249da44eff5ac0843dc28de22112299 (diff)
downloadperl-cbce292e0bfa19940c2aac7701c8ae7ca79366e5.tar.gz
[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.
-rw-r--r--pp.c7
-rw-r--r--t/op/list.t29
2 files changed, 19 insertions, 17 deletions
diff --git a/pp.c b/pp.c
index 3ec401d8b2..49798e2d93 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 d3f6b50661..c7056d0245 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");
}
{