2

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
0

1 Answer 1

2

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 $!; 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.