Effective Perl by Joseph N. Hall

Observations and Tips from the author of Effective Perl Programming

Monday, January 23, 2006

Tip: Reading a Few Lines from a File

How would you read a specific number of lines - say, 10 - from standard input? There's a plain old way:

my @lines;
for (my $i = 0; $i < 10; $i++) {
my $line = <STDIN>;
push @lines, $line;

This reads in 10 lines, one at a time, and appends them in order to the array @lines. Another perhaps cleverer way might be:

my @lines = map <STDIN>, 1..10;

I say "might" because this doesn't actually work. It looks as if you are using the ten numbers 1 through 10 to read 10 lines from standard input, which seems reasonable at first, because the .. ("dot-dot") operator returns a list of numbers when used in a list context. But the left hand expression you pass to map is also evaluated in a list context, and so the <STDIN> operator returns a list of all the remaining lines in the file. In other words, you ask for 10 lines but you get them all. You need to force a scalar context on the first argument in order to make <STDIN> to return one line at a time:

my @lines = map scalar(<STDIN>), 1..10;

Should there be fewer than 10 lines in your input, the array @lines will be padded with enough undefs to make up the difference because your attempts to read past end of file will return undef.


Post a Comment

Links to this post:

Create a Link

<< Home