Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Just 1 line explanation

by Nik (Initiate)
on Mar 19, 2007 at 10:02 UTC ( [id://605446]=perlquestion: print w/replies, xml ) Need Help??

Nik has asked for the wisdom of the Perl Monks concerning the following question:

Can you please explain me with simple words what the following perl code does? Thank you
unless ( grep { $_ eq param('select') } @display_files )

Replies are listed 'Best First'.
Re: Just 1 line explanation
by davorg (Chancellor) on Mar 19, 2007 at 10:12 UTC

    It goes through the values in @display_files, checking each of them in turn against the value of param('select') (which is almost certainly a CGI input parameter).

    As the "grep" function is called in scalar context ("unless" evaluates its arguments in scalar context) then it returns the number of items in @display_files that matched param('select'). If that number is zero then the "unless" returns true.

    Or more simply, it looks to see if the value of param('select') is found in @display_files and if it's not there, the code following the "unless" condition is executed.

    And it does it all in a rather inefficient manner. A more efficient version might look something like this:

    my $select = param('select'); my $found; foreach (@display_files) { if ($_ eq $select) { $found = 1; last; } } unless ($found) { # do something }

    See perldoc -f grep for more explanation of "grep" and perldoc perlsyn for more explanation of "unless".

      A more efficient version might look something like this:
      my $select = param('select'); my $found; foreach (@display_files) { if ($_ eq $select) { $found = 1; last; } }
      ... or use List::Util and
      my $select = param('select'); my $found = List::Util::first { $_ eq $select } @display_files;
      Anno

      Update: Code corrected, thanks pKai.

        benchmarks are funny things. have i made a mistake here, or is grep faster than first in this case? the real win is factoring out the call to param():
        use strict; use Benchmark qw(cmpthese); use List::Util; ## a 'reasonable' worst-case scenario? first of list of twenty .. my @display_files = qw( one two three four five six seven eight nine ten eleven twelve thi +rteen fourteen fifteen sixteen seventeen eighteen nineteen twenty ); sub param { 'one' } cmpthese( -2, { grep_param => sub { unless( grep { $_ eq param('select') } @display_files ) { 1; } + }, param_grep => sub { my $select = param('select'); unless( grep { $_ eq $select } @display_files ) { 1; } }, found => sub { my $select = param('select'); my $found; foreach (@display_files) { if ($_ eq $select) { $found = 1; last; } } unless ($found) { 1; } }, first => sub { my $select = param('select'); my $found = List::Util::first { $_ eq $select } @display_files +; unless ($found) { 1; } } });
        produces:
                       Rate grep_param      first param_grep      found
        grep_param  47285/s         --       -69%       -81%       -92%
        first      154996/s       228%         --       -36%       -73%
        param_grep 244086/s       416%        57%         --       -57%
        found      565517/s      1096%       265%       132%         --
        
        interestingly, change sub param to return undef (to get a failing test) and i get:
                       Rate grep_param      first      found param_grep
        grep_param  81919/s         --       -18%       -61%       -68%
        first       99685/s        22%         --       -52%       -61%
        found      207714/s       154%       108%         --       -18%
        param_grep 254449/s       211%       155%        22%         --
        
        personally, i think grep is the clearest and most familiar idiom, and for a shortish list of @display_files the performance gains of using the for () { ... last; } aren't worth it, especially if the failure case is common.
      Thank you very much for the detailed explanation.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://605446]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2024-04-23 14:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found