Reputation: 787
My Input File:
103M:A|PDBID|CHAIN|SEQUENCE
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG
Script1:
open(FH,"103m.txt")||die "error";
while(<FH>)
{
print <FH>;
}
script2:
open(FH,"103m.txt")||die "error";
while(<FH>)
{
print $_;
}
My script1 output:
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQ
Script2 output:
103M:A|PDBID|CHAIN|SEQUENCE
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG
Upvotes: 2
Views: 49
Reputation: 53478
This is actually an interesting question, because there's two different perl concepts in play.
The first is - <FH>
causes a line to be read from the file.
So if you:
while ( <FH> ) {
What you're actually getting is:
while ( defined $_ = <FH> ) {
}
And a line is being read from the file handle, put in $_
and then it's tested if it's 'defined' (e.g. the read was ok) - and if it wasn't, it exits the loop.
Because in the first example - you don't print $_
- that line is effectively discarded.
But the second think in play is about context.
<FH>
works differently if you do:
my $line = <FH>;
And:
my @lines = <FH>;
In the former case - a single line is read (up to the next $/
- by default \n
). In the latter, the whole file will be read, one "line" per array element.
Now, this is important because the while
loop read - is in a scalar context (one line at a time). But the print <FH>
is a list context - and will cause the whole file to be read (and printed).
So in your first example - you're iterating the loop once. Discarding the first line, and printing everything else.
And in the second loop - you're iterating once per line, and printing each line.
The difference isn't obvious on a 2 line file, but:
#!/usr/bin/env perl
use strict;
use warnings;
my $count;
while ( <DATA> ) {
print "Loop count ", ++$count,"\n";
print '$_ is "', $_,"\"\n";
print "Printing <DATA>\n";
print <DATA>;
}
__DATA__
line 1
line 2
line 3
line 4
line 5
This will output:
Loop count 1
$_ is "line 1
"
Printing <DATA>
line 2
line 3
line 4
line 5
But to take your second example:
#!/usr/bin/env perl
use strict;
use warnings;
my $count;
while ( <DATA> ) {
print "Loop count ", ++$count,"\n";
print '$_ is "', $_,"\"\n";
print 'printing $_',"\n";
print $_;
}
__DATA__
line 1
line 2
line 3
line 4
line 5
Which gives:
Loop count 1
$_ is "line 1
"
printing $_
line 1
Loop count 2
$_ is "line 2
"
printing $_
line 2
Loop count 3
$_ is "line 3
"
printing $_
line 3
Loop count 4
$_ is "line 4
"
printing $_
line 4
Loop count 5
$_ is "line 5"
printing $_
line 5
NB - there's no chomp
in the above, so $_
includes newlines.
And whilst we're at it - that form of open
isn't good practice. I would suggest instead:
open ( my $input, '<', "103m.txt" ) or die $!;
Upvotes: 2