in reply to Just 1 line explanation

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".

Replies are listed 'Best First'.
Re^2: Just 1 line explanation
by Anno (Deacon) on Mar 19, 2007 at 10:59 UTC
    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.
        I ran your benchmarks with similar results. With (much) longer lists first does come up second, still beaten by found. The low overhead of found's direct loop seems hard to beat.

        Anno

Re^2: Just 1 line explanation
by Nik (Initiate) on Mar 19, 2007 at 11:30 UTC
    Thank you very much for the detailed explanation.