http://qs321.pair.com?node_id=11115834

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

Was showing my kid some perl and was explaining to him what $_ and regexes were. I ran into something unexpected. I had him create the following to print the first two words of each line from a file:

open (my $fh, '<text.txt'); while (<$fh>) { /^([^ ]+) ([^ ]+)/; print "$1 $2" . "\n" if $1 && $2; }

It seems innocent enough. However, it gave me some unexpected results. If the file contains this:

hello one two three kjsf kjsd kjd
The output is:
hello one hello one hello one hello one

That's because no match is found on lines 2, 3 and 4 so it repeats $1 and $2 from line 1. However, if I change the program to this:

while (my $line = <$fh>) { $line =~ /^([^ ]+) ([^ ]+)/; print "$1 $2" . "\n" if $1 && $2; }
The output is the expected, single line:
hello one

So why does matching against $line reset $1 and $2 but matching against $_ does not?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks