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

Hi, I've come across this perl expression for printing the next line of a found regular expression and am amazed at how this works. Can someone give me some insight in how this works. For example this line will always display the line underneath the default route in the routing table. netstat -rn|perl -ne '$&&& print, /default|$/' Thanks J

Replies are listed 'Best First'.
Re: Obscure expression!
by davido (Cardinal) on Oct 13, 2004 at 19:46 UTC

    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

      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
Re: Obscure expression!
by Fletch (Bishop) on Oct 13, 2004 at 19:49 UTC

    If $& is true print $_; then match against $_ looking for either "default" or the end of the line. As a side effect, this match will set $& either to "default" (a true value) or the empty string (a false value).