in reply to Obscure expression!

A little spacing and expansion helps:

perl -ne '$& && print( $_ ), $_ =~ m/default|$/'

Take that one step at a time...

-n tells Perl to loop over the input, line by line, placing each line into $_, one line per iteration.

$& is the special variable that contains the string matched in the most recent pattern match. On the first iteration $_ is set to the first line, but $& is empty because we haven't yet executed a match.

&& is the short-circuit operator. It evaluates the LHS first. If the LHS is false (no value, or zero), it skips the right hand side. But if the lefthand side is true (contains a value that is non-zero, and not the empty string) it evaluates (executes) the right-hand side. On the right hand side is 'print'.

On the first iteration (as mentioned before), $& is empty, thus false. So nothing gets printed. Then the comma operator moves us along to the regexp matching. If $_ matches /default|$/, $& gets a value, and if it matched the 'default' portion of the alternation in the regexp, on the next iteration, the logical short-circuit will be true. And that being the case, the contents of $_ (on the next iteration) will be printed.

Some of this will make more sense if you have a look at perlrun and perlvar. This is what they're talking about when they say that Perl has a rich and compact syntax.


Dave

Replies are listed 'Best First'.
Re^2: Obscure expression!
by chopper1804 (Initiate) on Oct 13, 2004 at 20:07 UTC
    Thanks for your help. The reason it was so confusing was the '$&' and '&&' can/were pushed together ($&&&) and it worked the same way. Now we can use the following to print the matched line and the line after the matched line.
    perl -ne '$&&&print($&,"\n",$_), /default|$/'
    Thanks again for you quick and very helpful response. J