Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

List::Util - Bug in first?

by strat (Canon)
on Feb 18, 2008 at 14:06 UTC ( #668550=perlquestion: print w/replies, xml ) Need Help??
strat has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I just had a look at the function first in the Module List::Util and found the following code:

sub first (&@) { my $code = shift; foreach (@_) { return $_ if &{$code}(); } undef; # <====== BUG? }

In my eyes, the undef; should be replaced by a plain return; to prevent getting a (true!) list with one value (of undef), which in scalar context is true, e.g.

D:\workspace> perl D:\eclipse\workspace\BDC\lib> perl use strict; use warnings; use Data::Dumper; use List::Util; my @list = 1..20; my @first = List::Util::first { $_ == 21 } @list; print Dumper( \@first ); if( @first ) { print "In scalar-context: true\n"; } ^D $VAR1 = [ undef ]; In scalar-context: true
D:\workspace>perl -MList::Util -le "print $List::Util::VERSION" 1.19

Well, in the POD it is clearly stated that the first element is returned or undef - if not found. But since the syntax looks very similar to map and grep and the like, it might cause trouble without need if someone uses a list instead of a scalar to accept the result.

What do you think about?

Best regards,
perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8."

Replies are listed 'Best First'.
Re: List::Util - Bug in first?
by kyle (Abbot) on Feb 18, 2008 at 14:14 UTC

    The return value of first is always a scalar. I think it would be a bug to put it in list context as if it's going to return anything other than one thing. You might want it in list context with other things if the result of first will be a member of that list. In that case, returning nothing could ruin the placement of the other items.

Re: List::Util - Bug in first? (odds)
by tye (Sage) on Feb 18, 2008 at 16:12 UTC
    to prevent getting a (true!) list with one value (of undef), which in scalar context is true

    You can't get a list in a scalar context so your terminology is quite sloppy (but typical of those following this mantra of Perl Best Practices).

    Does your example code look like something that you would expect somebody to write and then be surprised at the results?

    In my experience, it is very unlikely for somebody to assign the results of a single function that always returns just one scalar to an array and then test the array (or the assignment) for "truth".

    If you make the suggested change, then you create the potential for a whole slew of "bugs" that together seem more plausible than the problem you "fix". Any place you might use first() in a list context now becomes "either a scalar or the empty list". It certainly makes for a serious problem in backward compatibility to change it now. Though, some unfortunate complexities of Perl prototypes actually make it quite awkward to use first() as part of a list, which reduces the likelihood of these types of problems in this case.

    push @results, first ...; @hash{ @list }= map { first {test($_)} candidates($_) } @list; use warnings; foo( { -option => first ... } );

    to just throw out a few examples.

    - tye        

Re: List::Util - Bug in first?
by ikegami (Pope) on Feb 18, 2008 at 16:22 UTC
    tye raised some good points as to why it shouldn't be done, and you haven't brought up any reason why it should be done. I once tried to come up with a situation where your proposed fix actually mattered, and didn't come up with anything. If you were looking for undef, you'd want to know more, such as the index at which the undef was found. If so, you'd use
    my $idx = first { !defined($a[$_]) || ... } 0..$#a;

      Thank you for your replies. Now I understand that it makes more sense that it is behaving like it is.

      Best regards,
      perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8."

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://668550]
Approved by Joost
[LanX]: fascinating ... the next MeetUp group around emacs is in Chicago ... checking flights...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2017-07-28 19:27 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (433 votes). Check out past polls.