A14
A14

Reputation: 71

perl while loops

I know how the seek works generally, and have looked at few other posts. However I am still confused. How does the Seek work exactly, would it read back from the same position it left off from?

while( my $line= <IN1>)
{
  do something;
  while( my $l= <IN2>)
  {
    do something;
    seek IN1, 0, 1;
  }
}

Would this go back to the first loop and start from where it left off...? and then if it went back to the second while loop how do i get it to readfrom where it left off...?

Upvotes: 0

Views: 732

Answers (3)

Axeman
Axeman

Reputation: 29844

Handles are going to "go back" from where they left off in the first place, as long as you don't open or close them in the loop--and you don't.

If what you want to do is stop reading from the second input and read from the first, then you just want to break from the inner loop. Because you didn't close or restart IN2, it should be ready to read the record after the one you read previously.

RCD_FROM_1:
while( my $line= <IN1>)
{
  do something;
  RCD_FROM_2:
  while( my $l= <IN2>)
  {
    do something;
    last RCD_FROM_2 if some_condition();
  }
}

You could also make that next RCD_FROM_1;

If you wanted to be able to reread the line, then you might do record a tell at the end of every loop, so that you could rewind and read that record again.

my $prev = 0;
RCD_FROM_1:
while( my $line= <IN1>)
{    
  ...

  $prev = tell( IN2 );
  RCD_FROM_2:
  while( my $l= <IN2>)
  {
    do something;
    if ( some_condition()) { 
        die 'Could not reset handle' unless seek( IN2, $prev, 0 );
        last RCD_FROM_2;
    }
    $prev = tell( IN2 );
  }

Myself, I would probably rather buffer the last record of both streams locally.

Upvotes: 2

Borodin
Borodin

Reputation: 126722

I think you are getting confused from my answer to your previous question which used seek to rewind a file and read it again from the beginning.

Perl's seek has nothing to do with while loops. It simply sets the position within a file where the next data will be read. I used it in my solution to return the read point to the start of a file once it had been completely read through.

For us to help you best you must rephrase your question and include detail about what you are really trying to do. At present, my best guess is this.

You have two files, each with four-line records that have a DNA sequence in the second line. You want a list of all DNA sequences that appear anywhere in both files, as well as a list of those sequences that are only in one file or the other.

Whether or not that is correct, please raise a new question that explains your problem in detail. You have gone for a specific solution that will not solve your problem, and asked for help to make it work. If you tell us about the problem instead of your proposed solution then we will be able to help you much better and will not have to make guesses about the true situation.

Upvotes: 2

Oleg V. Volkov
Oleg V. Volkov

Reputation: 22421

No, it won't go anywhere. This particular seek is a no-op, because, according to seek documentation you're effectively telling it to "move 0 bytes from current position". If you need to note your position in file and then resume there, you need to get it with tell and then seek with WHENCE set to SEEK_SET (0).

Example:

use Fntl qw(SEEK_SET); # <- he knows exactly what SEEK_SET is on your system, though it is always 0, AFAIR.
    
my $current_position = tell $file_handle;
do_stuff_with_data_from(<$file_handle>);
do_more_stuff_with_data_from(<$file_handle>);
# rewind
seek $fh, $current_position, SEEK_SET;

Upvotes: 3

Related Questions