-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
List slice *sometimes* ignores undefined items #12335
Comments
From jrw32982@yahoo.com@x = ( (2)[0,1,2] ); produces: $VAR1 = [ This seems inconsistent. The first result (for @x) was expected. The second (for @y) wasn't. I have tested this on linux ActivePerl from 5.8 through 5.16 with identical results. |
From @jkeenanOn Sun Aug 19 08:27:12 2012, jrw32982@yahoo.com wrote:
I don't think it's particularly inconsistent. In the first case the If anything, I think the second case is more intuitively plausible than I couldn't find anything in Camel book 3rd or 4th edition that clarifies Thank you very much. |
The RT System itself - Status changed from 'new' to 'open' |
From @cpansproutOn Sun Aug 19 08:27:12 2012, jrw32982@yahoo.com wrote:
I have often relied on the fact that list slices return nothing for -- Father Chrysostomos |
From @ap* James E Keenan via RT <perlbug-followup@perl.org> [2012-08-21 03:55]:
It is completely inconsistent with the way slices work in every other |
From @ikegamiOn Tue, Aug 21, 2012 at 3:26 AM, Father Chrysostomos via RT <
Except they don't. Sometimes they return nothing, sometimes they return |
From rick@bort.caOn Aug 31 2012, Aristotle Pagaltzis wrote:
It is no accident. From perldata: A slice of an empty list is still an empty list. Thus: @a = ()[1,0]; # @a has no elements But: @a = (1)[1,0]; # @a has two elements This makes it easy to write loops that terminate when a null list is while ( ($home, $user) = (getpwent)[7,0]) { -- |
@cpansprout - Status changed from 'open' to 'rejected' |
From @ap* Rick Delaney <rick@bort.ca> [2012-08-31 06:10]:
I do not think your quotation says about this what you think it says.
The bug report was about the surprising difference between these: @x = ( (2)[0,1,2] ); In both cases the slice is of a one-element list, not of an empty list, Regards, |
From @ikegamiOn Fri, Aug 31, 2012 at 12:51 AM, Aristotle Pagaltzis <pagaltzis@gmx.de>wrote:
Actually, it is covered: @c = (0,1)[2,3]; # @c has no elements |
From @perhunterOn 08/31/2012 12:51 AM, Aristotle Pagaltzis wrote:
look at the @c example which is the same as your @y line. slicing only my view is the docs could use a little more clarity saying that a slice uri |
From Eirik-Berg.Hanssen@allverden.noOn Fri, Aug 31, 2012 at 7:20 AM, Uri Guttman <uri@stemsystems.com> wrote:
... or just explain why C<< (0,1)[2,3] >> is an example of "a slice of an Eirik |
From @ap* Eric Brine <ikegami@adaelis.com> [2012-08-31 07:15]:
D’oh. That is not a particularly empty list, the introductory verbiage @a = 1..2; It is an understatement to say I’m not wild about this design, but if Patch attached. |
From @apfix-perldata-empty-list-slice.diffdiff --git i/pod/perldata.pod w/pod/perldata.pod
index 3a4776c..9bff98f 100644
--- i/pod/perldata.pod
+++ w/pod/perldata.pod
@@ -777,13 +777,18 @@ A slice of an empty list is still an empty list. Thus:
@a = ()[1,0]; # @a has no elements
@b = (@a)[0,1]; # @b has no elements
- @c = (0,1)[2,3]; # @c 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
+
This makes it easy to write loops that terminate when a null list
is returned:
|
From jrw32982@yahoo.comPlease see the example below. First, as the example below shows, there are inconsistencies depending on whether or not the list is held in a variable (@a1 or @a4) or a constant ((8) or ()) or a function return value. I don't see how these can be anything other than one or more bugs. Second, if there is intention (as Uri says and perldata says) to return an empty list when the list being sliced is an empty list, then there is a bug (as shown below) when the empty list is held in a variable @a4 vs. an empty list constant or an empty list returned from a function f4. Third, perhaps the documentation could be enhanced to make this intentional inconsistency (in the handling of list slices when the subscripts are off the end of the list and the list goes from non-empty to empty) more obvious in documentation, since it is surprising due to the inconsistency. -- John #!/usr/bin/perl sub f1 { return (9) } sub f4 { return () } print Data::Dumper->Dump([\@x1, \@y1], [qw[x1 y1]]);
|
From jrw32982@yahoo.comI'm not wild about it either, since it is inconsistent, but it is documented. It certainly threw me for a loop when I encountered it in live code.
|
From @cpansproutOn Fri Aug 31 06:40:15 2012, jrw32982@yahoo.com wrote:
@a[1] and (@a)[1] are different creatures. The former is an array
-- Father Chrysostomos |
From @cpansproutOn Fri Aug 31 06:09:29 2012, aristotle wrote:
Thank you. Applied as f51152e. -- Father Chrysostomos |
From jrw32982@yahoo.com_______________________________
OK. But I don't see what that has to do with this bug report. I don't believe I ever used code like that in my submission. I used (@a[1]). But regardless, if I leave off the surrounding parens, I get the same result. Have we agreed that we have a unambiguous bug? Here is the revised test program that still shows the bug. #!/usr/bin/perl sub f1 { return (9) } sub f4 { return () } print Data::Dumper->Dump([\@x1, \@y1], [qw[x1 y1]]); |
From @cpansproutOn Fri Aug 31 09:14:20 2012, jrw32982@yahoo.com wrote:
Which is an array slice, not a list silce.
If you add parentheses, and use (@a)[1], you will get consistent results.
No. The example below uses both array slice and list slice. If you use
-- Father Chrysostomos |
From @cpansproutOn Sat Sep 01 16:02:23 2012, jkeenan wrote:
Well, the original bug report was not a bug. But some of the -- Father Chrysostomos |
From jrw32982@gmail.comSomehow, I'm not explaining this properly. This is not just a doc The bug is the inconsistency of the behavior of list and array slices The only excuse for keeping the status quo would be backwards It has taken me many tries before I came up with the simplest I have added to my test cases below to show this issue with all the P.S. I don't think it's helping that either my reader or your reader use strict; sub f1 { return (9) } my @x1 = @a1[2,0,1]; # [ undef, 7, undef ] sub f5 { return () } my @x5 = @a5[2,0,1]; # [ undef, undef, undef ] print Data::Dumper->Dump([\@x1, \@y1], [qw[x1 y1]]); On Sat, Sep 1, 2012 at 9:14 PM, John Wiersba <jrw32982@yahoo.com> wrote:
|
From @ap* John Wiersba <jrw32982@gmail.com> [2012-09-02 07:45]:
Don’t worry, you made yourself understood.
No. It is a dubious design, maybe a design bug. It *is* surprising and
But actually, this is very different: *once you know*, it is very easy It is extremely surprising however, if you do not know. The lack of parallelism between arrays and lists makes me very unhappy. But if it was designed this way and documented as it is for such a long
I don’t think anyone is missing any point because of formatting. Your Regards, |
From @cpansproutOn Sun Sep 02 05:51:27 2012, aristotle wrote:
I am using the RT web interface. I think I know what is going on now. -- Father Chrysostomos |
From jrw32982@yahoo.com
OK, I see that's one way of looking at it. However my way of looking at it is that there's an implementation bug which has been documented (but maybe not documented well enough?). There is a limit at which we should consider something an implementation bug rather than just some quirk to be documented. For example, if "print 7" prints "q" and it's documented as such, it's still a bug that should be fixed. But I do agree with your point below that if there's a lot (where "lot" needs to be defined) of code which depends on the bug, then maybe it shouldn't be fixed.
The rule took me a long time to figure out (or even to figure out that there was a rule). From my initial investigation, which I originally coded, I thought the rule was: a slice returns undef for each specified index which is off the end of the array or list. Big mistake! That only works if 1) it's an array slice rather than a list slice, or 2) if the list slice has at least one index not out-of-bounds. The actual complete rule seems to be: 1. An array slice always returns one item for each index specified, returning undef for each out-of-bounds index. But the real problem is that this situation doesn't come up often enough in real life to remember. I don't mind remembering little edge cases if they come up often and they provide value. But when they come up infrequently they are effectively bugs because programmers will not remember them and will assume that there is no inconsistent edge case. That's what I encountered in my production code (and I have been writing perl for 15 years, so I am not a newbie). BTW, this is part of what people don't like about perl: that it has *too many* inconsistent edge cases and magic idioms. But if it was designed this way and documented as it is for such a long
Well, better late than never. :-)
It must be that U+00A0 is added when there are 2+ consecutive spaces. I added extra spaces to make the code line up if viewed in a monospace font. -- John |
From @cpansproutOn Sun Sep 02 13:34:41 2012, jrw32982@yahoo.com wrote:
The change to the current behaviour was made in commit c73bf8e. +=item Treatment of list slices of undef has changed So it seems the new behaviour was not actually implemented as intended. -As a special rule, if a list slice would produce a list consisting Four months later, in commit 56d7751, the documentation was corrected A slice of an empty list is still an empty list. Thus: @a = ()[1,0]; # @a has no elements So maybe this should change to what is documented in perl56delta.pod. -- Father Chrysostomos |
@cpansprout - Status changed from 'rejected' to 'open' |
From jrw32982@yahoo.com
FC: thanks for checking into this. I was a little scared that I'd missed a case after I read the comments that you unearthed (above). But after running a new test script against perl 5.8.9 and 5.14.2, the results still seem to agree with my list of rules (above). The results apparently do *not* depend on the *value* of the specified elements (whether or not they're undefined), but only on whether or not the specified indexes are in-bounds or out-of-bounds. -- John |
From @ap* Father Chrysostomos via RT <perlbug-followup@perl.org> [2012-09-03 01:20]:
Phew. I’m very glad to hear the current behaviour was not by design,
That actually makes sense. There’s still an asymmetry with arrays, @a = (); but this is far less bewildering because @a = ('a'..'c'); and the empty-list-only exemption is in fact useful in just the way And this special case is much easier to explain: “slices of empty Let’s have it that way. -- |
From @doyOn Thu, Sep 20, 2012 at 09:02:43AM -0700, John Wiersba wrote:
All the information in perlrepository was moved to either perlhack or -doy |
From @cpansproutOn Thu Sep 20 08:07:24 2012, jrw32982@yahoo.com wrote:
Yes, that’s fine. -- Father Chrysostomos |
From jrw32982@yahoo.comThanks, Jesse. It see the perlhack page on perldoc.perl.org, but Also, when I built perl from blead, for some reason, it didn't build perldoc. I built perl like this: mkdir ~/perl ~/perl/src Then, in order to get Configure to work with -des, I used: ./Configure -des -Dusedevel -Dprefix=~/perl At this point, I have ~/perl/bin filled with: but no perldoc in there. Is that because I built the development release? One further question: in order to test Father's patch, should I have built the development (5.17) release, or should I have built 5.16? Thanks!
|
From @cpansproutSorry you got no response. I missed this message. On Thu Sep 20 09:59:19 2012, jrw32982@yahoo.com wrote:
------------------------^^^^^^^^^^^^^
See my crude ASCII arrow. :-)
The latest snapshot of the development (blead) branch is the best thing
-- Father Chrysostomos |
From @ap* Father Chrysostomos via RT <perlbug-followup@perl.org> [2012-09-19 19:00]:
Sorry it took so long to get around to this. In the 2 weeks you needed How’s the attached look to you? John? -- |
From @ap0001-perldata-document-corrected-list-slicing-behaviour.patchFrom 385013a1eff5855e500f7f6a2657260f0673cf19 Mon Sep 17 00:00:00 2001
Message-Id: <385013a1eff5855e500f7f6a2657260f0673cf19.1381382810.git.pagaltzis@gmx.de>
From: Aristotle Pagaltzis <pagaltzis@gmx.de>
Date: Thu, 10 Oct 2013 07:24:10 +0200
Subject: [PATCH] perldata: document corrected list slicing behaviour
---
pod/perldata.pod | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/pod/perldata.pod b/pod/perldata.pod
index 254884d..7dc4cde 100644
--- a/pod/perldata.pod
+++ b/pod/perldata.pod
@@ -879,26 +879,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;
}
--
1.8.3.4
|
From jrw32982@yahoo.comThanks for working on this, Aristotle! I don't think what you wrote is quite right, in that it implies that the special exception is only empty lists. But really, the exception is not the contents of the list (whether or not it's empty), but the "quality" of the indexes (whether or not they are all in-bounds, or some of them are out-of-bounds). $ perl -le 'print "<$_>" for ("x")[1,2]' So, this unusual behavior happens not only for empty lists, but for any list where all the indexes are out of bounds. Here are my notes trying to explain this behavior to myself: - An array (or hash) slice always returns one item for each index This behavior is so weird (inconsistent, unexpected) that I don't think examples alone will do it justice. It has to be written out in words, something similar to your explanation for empty lists, or my wording above.
|
From @ap* John Wiersba <jrw32982@yahoo.com> [2013-10-10 19:15]:
Yes, that is how it works now. I already patched the documentation to But this doc patch is for the patch that FatherC submitted, which, as Does it not? Regards, |
From jrw32982@yahoo.comI just tried my example below on 5.19.5 and it works the same way as I show below (the same as 5.10 - 5.18).
|
From @ap* John Wiersba <jrw32982@yahoo.com> [2013-10-11 21:05]:
Yes, FC’s patch has not been applied, so any released version of perl My question was whether you feel the phrasing I proposed conveys the -- |
From jrw32982@yahoo.comYes, I think your doc patch is clear, especially because it used the words "special exception". It might also be helpful to include some example for contrast showing differing behavior with array and hash slices vs a list slice, since the distinction between "list" and "array" is not always clear.
|
From @ap* Aristotle Pagaltzis <pagaltzis@gmx.de> [2013-10-10 07:40]:
Bump. It would be nice for this to make it into 5.20. Regards, |
From @ap* Aristotle Pagaltzis <pagaltzis@gmx.de> [2014-03-11 08:20]:
Maybe if I try with the patch inlined it’ll get comments quicker. :-) |
From @ap0001-perldata-document-corrected-list-slicing-behaviour.patchFrom 385013a1eff5855e500f7f6a2657260f0673cf19 Mon Sep 17 00:00:00 2001
Message-Id: <385013a1eff5855e500f7f6a2657260f0673cf19.1381382810.git.pagaltzis@gmx.de>
From: Aristotle Pagaltzis <pagaltzis@gmx.de>
Date: Thu, 10 Oct 2013 07:24:10 +0200
Subject: [PATCH] perldata: document corrected list slicing behaviour
---
pod/perldata.pod | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/pod/perldata.pod b/pod/perldata.pod
index 254884d..7dc4cde 100644
--- a/pod/perldata.pod
+++ b/pod/perldata.pod
@@ -879,26 +879,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;
}
--
1.8.3.4
|
From @apHi perl5-porters, * Aristotle Pagaltzis <pagaltzis@gmx.de> [2014-05-11 12:15]:
Also now as a patience diff, much nicer. |
From @ap0001-perldata-document-corrected-list-slicing-behaviour.patchFrom 385013a1eff5855e500f7f6a2657260f0673cf19 Mon Sep 17 00:00:00 2001
Message-Id: <385013a1eff5855e500f7f6a2657260f0673cf19.1381382810.git.pagaltzis@gmx.de>
From: Aristotle Pagaltzis <pagaltzis@gmx.de>
Date: Thu, 10 Oct 2013 07:24:10 +0200
Subject: [PATCH] perldata: document corrected list slicing behaviour
---
pod/perldata.pod | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/pod/perldata.pod b/pod/perldata.pod
index 254884d..7dc4cde 100644
--- a/pod/perldata.pod
+++ b/pod/perldata.pod
@@ -879,26 +879,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:
-
- @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
+
+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 = ()[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;
}
--
1.8.3.4
|
From @rjbsAristotle, if you have fact-checked the changes against bleadperl, please feel -- |
From jrw32982@gmail.comSee my reply below. It bounced when sending it from yahoo. On Tue, May 13, 2014 at 8:52 AM, John Wiersba <jrw32982@yahoo.com> wrote:
|
From @khwilliamsonOn 05/11/2014 04:27 AM, Aristotle Pagaltzis wrote:
What is the status on applying this? |
From @ap* Karl Williamson <public@khwilliamson.com> [2014-06-16 22:45]:
The underlying core patch has not been applied and so this doc patch I found that FC’s patch no longer applies cleanly and made an ad-hoc And there it sits for now, on my todo list, along with my doc patch. Regards, |
From @cpansproutOn Mon Jun 16 15:26:27 2014, aristotle wrote:
I have applied my core patch as cbce292 and your doc patch as e2ec1b0. Thank you. -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'pending release' |
From @cpansproutOn Thu Dec 04 06:56:03 2014, aristotle wrote:
Speaking of semantics bugs, would you be willing to look at #123367? -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Thu Dec 04 06:56:03 2014, aristotle wrote:
Speaking of semantics bugs, would you be willing to look at #123367? -- Father Chrysostomos |
From @khwilliamsonThanks for submitting this ticket The issue should be resolved with the release today of Perl v5.22. If you find that the problem persists, feel free to reopen this ticket -- |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
From jrw32982@gmail.com
Thanks, Karl (and all of p5p)! The world will be a better place |
Migrated from rt.perl.org#114498 (status was 'resolved')
Searchable as RT114498$
The text was updated successfully, but these errors were encountered: