views:

272

answers:

3

Consider the following silly Perl program:

$firstarg = $ARGV[0];

print $firstarg;

$input = <>;

print $input;

I run it from a terminal like:

perl myprog.pl sample_argument

And get this error:

Can't open sample_argument: No such file or directory at myprog.pl line 5.

Any ideas why this is? When it gets to the <> is it trying to read from the (non-existent) file, "sample_argument" or something? And why?

+1  A: 

By default, perl consumes the command line arguments as input files for <>. After you've used them, you should consume them yourself with shift;

Paul Tomblin
You have it backwards. Perl doesn't do anything with `@ARGV` by default. It's the behavior of `<>` that's special.
Michael Carman
That's what I was saying. That <> uses @ARGV unless you consume them yourself with shift.
Paul Tomblin
+10  A: 

<> is shorthand for "read from the files specified in @ARGV, or if @ARGV is empty, then read from STDIN". In your program, @ARGV contains the value ("sample_argument"), and so Perl tries to read from that file when you use the <> operator.

You can fix it by clearing @ARGV before you get to the <> line:

$firstarg = shift @ARGV;
print $firstarg;
$input = <>;       # now @ARGV is empty, so read from STDIN
print $input;
mobrule
Aha! Changing it to <STDIN> worked fine :)
Jimmeh
+7  A: 

See the perlio man page, which reads in part:

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.

If you want STDIN, use STDIN, not <>.

Sean