parse(*ARGV)
is the simplest solution: the explanation is a bit long, but an important part of learning how to use Perl effectively is to learn Perl.
When you use a null filehandle (<>
), it actually reads from the magical ARGV
filehandle, which has special semantics: it reads from all the files named in @ARGV
, or STDIN
if @ARGV
is empty.
From perldoc perlop
:
The null filehandle <>
is special: it can be used to emulate the
behavior of sed and awk. Input from <>
comes either from standard
input, or from each file listed on the command line. Here’s how it
works: the first time <>
is evaluated, the @ARGV
array is checked, and
if it is empty, $ARGV[0]
is set to "-"
, which when opened gives you
standard input. The @ARGV
array is then processed as a list of
filenames. The loop
while (<>) {
... # code for each line
}
is equivalent to the following Perl-like pseudo code:
unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
open(ARGV, $ARGV);
while (<ARGV>) {
... # code for each line
}
}
except that it isn’t so cumbersome to say, and will actually work. It
really does shift the @ARGV
array and put the current filename into the
$ARGV
variable. It also uses filehandle ARGV
internally--<>
is just a
synonym for <ARGV>
, which is magical. (The pseudo code above doesn’t
work because it treats <ARGV>
as non-magical.)
You don't have to use <>
in a while
loop -- my $data = <>
will read one line from the first non-empty file, my @data = <>;
will slurp it all up at once, and you can pass *ARGV
around as if it were a normal filehandle.