Telemachus wrote:
This came up somewhere else, people disagreed and now I can't see it
clearly anymore. Imagine you have an array filled with numbers, and
you only want to print out the even ones. Fine, someone says, use
grep.

print "$_\n" for grep {$_ % 2 == 0} @testAr;

But is this a void context?

No. grep() is in list context because the for (foreach) statement modifier defines a list context:

perldoc perlsyn
[ SNIP ]
       Statement Modifiers

       Any simple statement may optionally be followed by a SINGLE
       modifier, just before the terminating semicolon (or block
       ending).  The possible modifiers are:

           if EXPR
           unless EXPR
           while EXPR
           until EXPR
           foreach LIST


On the one hand you're not literally
throwing away the results, but on the other hand you're also not
looking to keep the list that grep builds itself. So in a sense, you
seem to be creating a list just to iterate over it in the print
statement. That seems to be what the Pelr FAQ has in mind here, "This
means you're making Perl go to the trouble of building a list that you
then just throw away.

You are not throwing it away, you are passing it through to the for statement modifier, which iterates over that list.


If the list is large, you waste both time and
space. If your intent is to iterate over the list, then use a for loop
for this purpose."

So in a context like this, would the following be better?

for my $num (@testAr) {
    if (($num % 2) == 0 ) {
        print "$num\n";
    }
}

That code is iterating over a larger list, assuming that @testAr contains *some* odd numbers.


So I guess my question is this: Does the FAQ (and advice like it) mean
to avoid using grep *unless* you actually want to keep and use the
list, or does it just mean don't use grep only for side effects?

Void Context:

grep {$_ % 2 == 0} @testAr;


Scalar Context:

my $count = grep {$_ % 2 == 0} @testAr;
if ( grep {$_ % 2 == 0} @testAr ) {
while ( grep {$_ % 2 == 0} @testAr ) {


List Context:

my @evens = grep {$_ % 2 == 0} @testAr;
print grep {$_ % 2 == 0} @testAr;


For grep() to produce a side effect you would have to use a function/operator in the conditional that produced a side effect or modify $_ in the conditional.

I don't know why you would *want* to use grep() in void context that can't be done better some other way?



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to