The other answers have explained the statement modifier form of the while
loop. However, there's a lot of other magic going on here. In particular, the script relies on three of Perl's special variables. Two of these ($_
and $!
) are very common; the other ($.
) is reasonably common. But they're all worth knowing.
When you run while <$fh>
on an opened filehandle, Perl automagically runs through the file, line by line, until it hits EOF
. Within each loop, the current line is set to $_
without you doing anything. So these two are the same:
while (<$fh>) { # something }
while (defined($_ = <$fh>)) { # something }
See perldoc perlop
, the section on I/O operators. (Some people find this too magical, so they use while (my $line = <$fh>)
instead. This gives you $line
for each line rather than $_
, which is a clearer variable name, but it requires more typing. To each his or her own.)
$!
holds the value of a system error (if one is set). See perldoc perlvar
, the section on $OS_ERROR
, for more on how and when to use this.
$.
holds a line number. See perldoc perlvar
, the section on $NR
. This variable can be surprisingly tricky. It won't necessarily have the line number of the file you are currently reading. An example:
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) {
print "$ARGV: $.\n";
}
If you save this as lines
and run it as perl lines file1 file2 file3
, then Perl will count lines straight through file1, file2 and file3. You can see that Perl knows what file it's reading from (it's in $ARGV; the filenames will be correct), but it doesn't reset line numbering automatically for you at the end of each file. I mention this since I was bit by this behavior more than once until I finally got it through my (thick) skull. You can reset the numbering to track individual files this way:
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) {
print "$ARGV: $.\n";
}
continue {
close ARGV if eof;
}
You should also check out the strict
and warnings
pragmas and take a look at the newer, three-argument form of open
. I just noticed that you are "unknown (google)", which means you are likely never to return. I guess I got my typing practice for the day, at least.