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

i am sorry if some has already posted this. why grep behaves differently , when we use expression and using the output of the expression directly in the place of expression

my $t = 1; print grep {$t^=1} qw( a b c d e );

and using 0 directly instead using expression $t^=1 below

my $t = 1; print grep {0} qw( a b c d e ); my $t = 1; print grep {$t} qw( a b c d e );

20090717 Janitored by Corion: Added formatting, code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: grep function usage
by cdarke (Prior) on Jul 13, 2009 at 13:35 UTC
    grep returns all elements for which the code block returns true. Like most languages, in Perl zero is considered false and one (non-zero) is true.
    {$t ^= 1} is carrying out an XOR operation, which produces a 1 if either of its inputs is 1 and a 0 if both 0 or 1. Therefore 1 (true) is produced for the second (b) and forth (d) iterations.

    Using just the number 1 means the result is true for all elements, so all are printed, while using zero (false) mean none are. Using $t directly is just another way of saying true, since its value is 1.
Re: grep function usage
by moritz (Cardinal) on Jul 13, 2009 at 12:55 UTC
    Note that the block that's passed to grep is executed for every list element.

    $t^=1 changes the value of $t (and thus the return value) on each execution, 0 or 1 don't.

Re: grep function usage
by Marshall (Canon) on Jul 13, 2009 at 13:56 UTC
    Perl grep does what Perl grep does. Perl grep is not like command line grep. Think of grep{} like a "filter" that operates on a list. If the thing within grep{$something} is TRUE, then the input is passed to the output, ie, a "filter"...THAT'S IT!

    Ok, look at this:

    my $t = 1; print grep {$t} qw( a b c d e ); What do you think that means? this is the same as: grep{1}qw( a b c d e ); and yields the exact same output as input list (a b c d e) grep {0} qw( a b c d e ); yields nothing! because this means foreach(a b c d e), pass each item to the output (to the left) if the thing within grep{} is true. BUT {0} is NOT true! So nothing is passed to your print. my $True_false = "False"; foreach (qw ( a b c d e )) { print if ($True_false eq "True"); print "" && $_; #another way #either way prints nothing!!! } Your very cute use of XOR is well, cute. my $t = 1; print grep {$t^=1} qw( a b c d e );
    The above code "toggles" the value within the grep{} between TRUE and FALSE. So you get every other list element. Odd or even depending upon whether $t starts at 0 or starts at 1. This "how do I get the even things in the list" is cute, but maybe a bit too cute?

    Anyway the code works exactly as expected.

    Update: Maybe the problem is that you don't know what $t^=1 means?
    $t+=1; means $t = $t + 1; #better as $t++, but no matter here..
    $t^=1; means $t = $t ^ 1;