marctwo has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks.

I know this has been asked before but my question is slightly different.

I am parsing a file and, when it reaches a line containing a certain value, I want to pass the filehandle to a sub in a different module and contunue parsing the file from the line I left off at. When the sub is finished I then want to resume in the calling routine from the line the sub finished at.

Is this clear? Can it be done this way or is there a better way?

Many Thanks,

Marc

Replies are listed 'Best First'.
Re: Passing filehandle to sub
by broquaint (Abbot) on Jun 09, 2003 at 11:03 UTC
    If you've opened it with a bareword then pass the glob, or if you've used a variable just pass that e.g
    ## bareword open open(FH, "yourfile") or die("oops - $!"); func_call( *FH ); ## variable open open(my $fh, "yourfile") or die("oops - $!"); func_call( $fh ); sub func_call { my $fh = shift; do_stuff($_) while <$fh>; }
    And if you need to revert back to previous positions in the file make use of the tell and seek functions.
    HTH

    _________
    broquaint

      Hi broquaint!

      I've got a question: since it seems that opening a file using a variable (instead of a bare word) only has advantages, like in this case, is there a reson or particular situation where it's better to use a bare word?

      Thanks, Michele.

        is there a reson or particular situation where it's better to use a bare word?
        Under the assumption that you're using 5.6+ I can't really think of any practical situations where a bareword filehandle is preferable to a lexical variable. Sure it's potentially less characters, by general practice visually distinctive in code and doesn't incur the overhead of a lexical variable (which, to be honest, is pretty much negligible in all but the most process intensive of operations) but I can't think of any practical situations where these factors outweigh the use of a lexical filehandle. I say practical situations because a bareword filehandle is great for obfuscation and golfing, but in code at large I'd say lexical filehandles would be prefered. If any monks can think of a situation where a bareword filehandle is indeed preferable to a lexical filehandle then please reply below.
        HTH

        _________
        broquaint

      I used the variable method you suggested and it seems to work fine.

      Thanks for your quick and helpful response!

      Marc

Re: Passing filehandle to sub
by fsn (Friar) on Jun 09, 2003 at 11:31 UTC
    I don't understand what you mean with that last sentence, do you really want to continue from the exact line the sub finished at? That menas you will have to read that line twice, once in the sub and once i the main routine, by pushing the line back into the buffer, or pass back that line to the main function using return values. Try to avoid that. I usually read a file in only one place and use some sort of state machine to control what I want to do with what I read.

    Anyway, if this is just a question regarding filhandle referencies, see the perlref and perlreftut. Also, I made a small example on filehandle referencing:

    #!/usr/bin/perl -w open SESAME, "testfil"; while (<SESAME>) { chomp; print "main: $_ "; if ($_ =~ /baz/) { print "go! \n"; &aSub(*SESAME) } print "\n"; } sub aSub { my $inFile = shift; while (<$inFile>) { chomp; print "sub: $_"; if ($_ =~ /bao/ ) { print " return!"; return }; print "\n"; } }
    the testfile is simple:
    foo bar baz bam bao fee fie
      fsn - you are correct, I meant to resume in the main at the next line and not the same line. Using broquaint's suggestion above seems to achieve this without the need for using any special commands like seek.

      Many thanks for your help.

      Marc

Re: Passing filehandle to sub
by Lachesis (Friar) on Jun 09, 2003 at 11:04 UTC
    Quick answer. The current line number for the file you're reading is stored in $. You can grab that and then use seek to set the postion of the file handle when you come back to your calling sub.
    Update: I answered that too quickly. You want to use tell to get the position to use with the seek.