Reputation: 839
I have simple question:
#! /usr/bin/perl
use warnings;
use strict;
my $protfile = "file.txt";
open (FH, $protfile);
while (<FH>) {
print (<FH>);
}
#! /usr/bin/perl
use warnings;
use strict;
my $protfile = "file.txt";
open (FH, $protfile);
while (my $file = <FH>) {
print ("$file");
}
Upvotes: 2
Views: 12154
Reputation: 11
while (<FH>) {
print (<FH>);
}
use this instead:
while (<FH>) {
print $_;
}
Upvotes: 1
Reputation: 72463
When used in scalar context, <FH>
returns the next single line from the file.
When used in list context, <FH>
returns a list of all remaining lines in the file.
while (my $file = <FH>)
is a scalar context, since you're assigning to a scalar. while (<FH>)
is short for while(defined($_ = <FH>))
, so it is also a scalar context. print (<FH>);
makes it a list context, since you're using it as argument to a function that can take multiple arguments.
while (<FH>) {
print (<FH>);
}
The while
part reads the first line into $_
(which is never used again). Then the print
part reads the rest of the lines all at once, then prints them all out again. Then the while
condition is checked again, but since there are now no lines left, <FH>
returns undef
and the loop quits after just one iteration.
while (my $file = <FH>) {
print ("$file");
}
does more what you probably expect: reads and then prints one line during each iteration of the loop.
By the way, print $file;
does the same as print ("$file");
Upvotes: 2
Reputation: 42154
Context.
Your first program tests for end-of-file on FH
by reading the first line, then reads FH
in list context as an argument to print
. That translates to the whole file, as a list with one line per item. It then tests for EOF again, most likely detects it, and stops.
Your second program iterates by line, each one read in scalar context to variable $file
, and prints them individually. It detects EOF by a special case in the while
syntax. (see the code samples in the documentation)
So the specific reason why your program doesn't print the first line in one case is that it's lost in the argument to while
. Do note that the two programs' structure is pretty different: the first only runs a single while
iteration, while the second iterates once per line.
PS: nowadays, the recommended way to manage files tends towards lexical filehandles (open my $file, 'name'; print <$file>;
).
Upvotes: 5
Reputation:
Because you are comsuming the first line with the <> operator and then using it again in the print, so the first line has already gone but you are not printing it. <> is the readline operator. You need to print the $_ variable, or assign it to a defined variable as you are doing in the second code. You could rewrite the first:
print;
And it would work, because print uses $_ if you don't give it anything.
Upvotes: 3