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
Bug when testing array returned by sort operator #5557
Comments
From david@whistlingcat.comCreated by dmellor@whistlingcat.comI believe I have discovered a bug in Perl 5.6.1, which I first noticed when #!/usr/bin/perl use strict; { if (Sub1(\@foo)) { my @tmp = Sub1(\@foo); if (Sub2(\@foo)) { @tmp = Sub2(\@foo); sub Sub1 return sort { $a->{preference} <=> $b->{preference} } sub Sub2 my @items = grep { $_->{type} eq 'MX' } @$array; Both of the subroutines in this script take an arrayref and extract some items Test 1 FAILED Perl Info
|
From @Abigail
No, it should not. Expressions in scalar context don't return lists, Your first invokation of Sub1 is in scalar context, hence the sort is Abigail |
From @schwernOn Tue, Jun 11, 2002 at 02:03:46AM -0700, Abigail wrote:
If this is good behavior, which I don't think it is, it isn't documented. The more logical thing for sort in scalar context to do is skip the sort and So if this returns 3: $ perl -wle '@a = qw(c b a); print scalar @a' why not this: $ perl -wle '@a = qw(c b a); print scalar sort @a' More importantly, the user can't tell the difference if the sort is returned # dangerous # safe and there's really no reason it should be so. The fix should be simple. pp_sort.c does this: if (gimme != G_ARRAY) { and it's a small matter of changing that RETURNPUSHUNDEF with something that This is very old functionality, going back to at least 5.004 and probably -- |
From [Unknown Contact. See original ticket]On tisdag, juni 11, 2002, at 09:20 , Michael G Schwern wrote:
If so, one could make the case that it should sort aswell. my @foo = qw(1 2 3); ? Arthur |
From @tamiasOn Tue, Jun 11, 2002 at 03:20:30PM -0400, Michael G Schwern wrote:
I disagree with this suggestion. First, returning the number of elements @x = sort('dog', 'cat', 'fish'); Second, if one wants the behavior that occurs without the sort, then I It would be just as logical, I think, for sort in scalar context to sort In this case, given all these possibilities, it's difficult to choose which
I don't think there's any reason it shouldn't be so. You have to be We do have wantarray(), after all.
I'm just not sure returning the number of elements is useful or what most Ronald |
From @rgarciaOn 2002.06.11 22:31 Ronald J Kimball wrote:
Note also that sort in scalar context warns with 5.8.0. |
From @schwernOn Tue, Jun 11, 2002 at 04:31:32PM -0400, Ronald J Kimball wrote:
Why would you sort a constant list? Is there any reasonable way to get this
You have a subroutine which returns a sorted list. A user wants to know how sub foo { ... return sort @list } and that doesn't DWIM. This is a problem. Removing the sort just causes
I find these options to be dubious. Having the ability to do any of the sort() returning undef solves no problems, it's just there because we can't
What suprise am I missing here? $ perl -wle 'sub foo { return map { $_ } ("dog", "cat", "fish") } $x = foo(); print $x' $ perl -wle 'sub foo { return grep { $_ } ("dog", "cat", "fish") } $x = foo(); print $x' $ perl -wle 'sub foo { return split / /, "dog cat fish" } $x = foo(); print $x' $ perl -wle 'sub foo { return sort("dog", "cat", "fish") } $x = foo(); print $x' o/` One of these things is not like the other o/` :) -- |
From @schwernOn Tue, Jun 11, 2002 at 10:56:53PM +0200, Rafael Garcia-Suarez wrote:
It does for these simple cases: $ perl5.8.0 -wle 'my $x = sort("dog", "cat", "fish")' $ perl5.8.0 -wle 'my $x = 42 if sort("dog", "cat", "fish")' but not for the problem case: $ perl5.8.0 -wle 'sub foo { return sort("dog", "cat", "fish") } $x = foo(); print $x' -- |
From @tamiasOn Tue, Jun 11, 2002 at 06:46:38PM -0400, Michael G Schwern wrote:
Why would you call sort in a scalar context? How about this, then: @x = sort($m, $n, $o);
This problem is properly solved by rewriting the subroutine to use sub foo { return wantarray ? sort @list : scalar(@list) }
Returning the first element seems like an obvious behavior, and other
We can't agree, and therefore changing the sort to return the number of I don't think that having sort() return the number of elements solves a
The behavior changes based on the context of the expression. If you don't Also note that the number returned grep, map, and split in scalar context Ronald |
From @schwernI was going to do another point-by-point reply, but I think I've got the There's three distict issues, and I'm only worried about #3. Issue #1: sort in boolean context. if( sort @array ) { ... } this is pretty straight-forward. It's useless, and 5.8.0 warns you as such. Issue #2: sort in simple scalar context. my $x = sort @array; this could potentially do many things. Return undef, return the number of Issue #3: sort in "variable" context. sub foo { ... return sort @array } The current behavior of this subroutine is surprising. Unlike similar sub foo { ... return @array } Those all will. And that's the surprise for the author and caller of foo(). Now, is this a common problem? Here's a little straw poll of all the CPAN $ perl -MDBI -le 'printf "You have %d DBI drivers\n", scalar DBI->available_drivers' That's funny. I could have sworn I'd installed some DBD modules. $ perl -MExtUtils::Installed -le '$i = ExtUtils::Installed->new; printf "I have %d modules installed\n", scalar $i->modules' AHHH! Where'd all my modules go!!!! ;) If Alan Burlison, Lincoln Stein, Andreas Koenig, Graham Barr and Tim Bunce -- |
From @gbarrOn Wed, Jun 12, 2002 at 12:13:03AM -0400, Michael G Schwern wrote:
If you ask a 3 year old "whats 1 + 1" and they reply 3, you say no its "2"
Why would you do that ?
I fail to see why this should be surprising if the return value of foo()
Define "work", what you really mean is that it will not do what YOU want
No, thats YOUR surprise. If you read the docs properly you will know what it would
Your pattern needs fixing as Net::LDAP::ASN does not call sort at all.
One could just as easily say that that was a bug in available_drivers, but then if it is
Not me ? So please don't use my name as justifaction for a bad premise Graham. |
From @TuxOn Wed 12 Jun 2002 11:09, Graham Barr <gbarr@pobox.com> wrote:
Undeliberately, as shown in Schwerns previous example unless (DBI->available_drivers) die "No DBI drivers available";
-- |
From [Unknown Contact. See original ticket]Michael G Schwern <schwern@pobox.com> writes:
It is supposed to be surprising. Most people expect $foo = sort ...; to return the largest/smallest entry so returning undef surprises
There was considerable heat on "What It Meant" last time around. -- |
From @schwernOn Wed, Jun 12, 2002 at 10:09:41AM +0100, Graham Barr wrote:
You wouldn't, that's why we warn about it. Like I said, not what I'm
<snip>
Because the author of foo() likely doesn't even know this behavior exists. I'm quite certain both DBI->available_drivers and
You're right, I should have looked deeper into it.
Explicitly documenting in every module that each function which returns an Tim didn't sit down one day and think, "Hmm, I really should prevent anyone -- |
From @schwernOn Wed, Jun 12, 2002 at 05:03:11PM +0100, Nick Ing-Simmons wrote:
We already have such a warning, but it only works for simple cases. $ perl5.8.0 -wle 'my $foo = sort qw(1 2 3); print $foo' $ perl5.8.0 -wle 'sub foo { return sort @_ } my $foo = foo(qw(1 2 3)); print $foo' It's the second case which is the surprise. The problem being that when you You certainly wouldn't expect to have to write it the "right" way sub foo { return wantarray ? sort @_ : @_ } would you? So that's why I think having sort return the number of elements in scalar You can even leave the compile-time warning on for the simple case. -- |
From @TimToadyOn Wed, 12 Jun 2002, Nick Ing-Simmons wrote:
I think returning an extreme ought to be explicit. Perl 6 breaks Larry |
From [Unknown Contact. See original ticket]Larry said:
Two votes (at least) for explicitness. Quicksort and merge sort |
From [Unknown Contact. See original ticket]Michael G Schwern <schwern@pobox.com> writes:
Presumably we could warn if sort was child of a 'return' or last statement -- |
From [Unknown Contact. See original ticket]John P. Linderman <jpl@research.att.com> writes:
But Larry's vote carries near-infinite weight...
But spotting my ($n) = sort ... Is much harder to do than the scalar/list context. But consider me convinced by the explicit argument - we -- |
From @schwernOn Wed, Jun 12, 2002 at 07:57:24PM +0100, Nick Ing-Simmons wrote:
use List::Util qw(max min maxstr minstr); Though it is unfortunate that max/min aren't generic. ie. my $max = max { your sort criteria } @array; but I think my nit-picking account is overdrawn. :) -- |
From [Unknown Contact. See original ticket]Nick Ing-Simmons wrote:
Isn't Want::want() able to do this? Or at least some of it?
Surely you mean, invent max_n and min_n, which would return the n my ($p, $q) = max_n { $a <=> $b } 2, @list; -- |
From [Unknown Contact. See original ticket]Benjamin Goldberg chimed in:
That's what I had in mind. But we want to be careful about the interface. (A qsort-like implementation runs the risk of the same quadratic |
From [Unknown Contact. See original ticket]Benjamin Goldberg <goldbb2@earthlink.net> writes:
I don't want that - it is too messy. Let perl6 solve the general problem. -- |
From @gbarrOn Wed, Jun 12, 2002 at 03:25:01PM -0400, Michael G Schwern wrote:
I agree its unfortunate, but the reason is because prototypes Graham. |
From @davidnicolhere's a Before: After: Inline Patch--- perl-current/pp_sort.c Sat Jul 31 11:44:58 2004
+++ dynamic-sort-in-scalar-warning/pp_sort.c Mon Aug 2 23:01:55 2004
@@ -1508,8 +1508,13 @@
void (*sortsvp)(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp)
= Perl_sortsv;
if (gimme != G_ARRAY) {
+ Perl_warner(
+ aTHX_ packWARN3(WARN_VOID,WARN_AMBIGUOUS,WARN_SYNTAX),
+ "sort called in dynamic non-array context,"
+ " try ()=sort ..."
+ );
SP = MARK;
RETPUSHUNDEF;
}
|
From @HugmeirOn Wed Aug 04 21:03:53 2004, davidnicol wrote:
Some bikeshedding here: If the warning the applied, I think that it --hugmeir |
From @cpansproutOn Fri May 25 17:37:27 2012, Hugmeir wrote:
I’m not sure this warning is such a good idea. If a module provides a sub to be called only in list context, that ends -- Father Chrysostomos |
@dcollinsn - Status changed from 'open' to 'stalled' |
Migrated from rt.perl.org#9528 (status was 'stalled')
Searchable as RT9528$
The text was updated successfully, but these errors were encountered: