http://qs321.pair.com?node_id=305233


in reply to Re: Re: desire to pass file handles by value
in thread desire to pass file handles by value

Now if only you could localize a variable that represents the file position, you wouldn't have to manually save/restore its value. Hmmm....
package Tie::Scalar::FHPos; use FileHandle; sub TIESCALAR { my( $pkg, $fh ) = @_; bless [$fh], $pkg; } sub FETCH { my( $self ) = @_; $self->[0]->tell } sub STORE { my( $self, $pos ) = @_; $self->[0]->seek($pos,0); }
Test:
open F, "< foo.dat"; our $pos; tie $pos, 'Tie::Scalar::FHPos', \*F; { local $pos = 20; print "$pos: ", scalar(<F>); } print "$pos: ", scalar(<F>);
Cool!

jdporter
The 6th Rule of Perl Club is -- There is no Rule #6.

Replies are listed 'Best First'.
Re: Re: Re: Re: desire to pass file handles by value
by ysth (Canon) on Nov 07, 2003 at 09:52 UTC
    Nice. It does have negative one side effect, though. If you are reading from some other file (say <STDIN>), and you reference $pos, the tell or seek will change perl's idea of the most recent input file to F. This will mess up the "<STDIN> line n" in any error/warning message, and also change what handle the $. var is looked up in.

    To fix this, put a local $.; in STORE and FETCH. (For some reason, this then triggers some warnings from STORE when $pos is localized. Fix by saying seek($pos||0,0)).

    If you are downvoting this for other than lack of interest, thanks for sending me a message or reply to let me know why so I can do better (or just stay quiet) next time.

      Ah, thanks for debugging that. When I tried it on STDIN, I got the fubar, and simply dismissed it with a "What do you expect, seeking back and forth on a non-file stream?" :-)
      But Perl is smarter than I am... as usual.

      jdporter
      The 6th Rule of Perl Club is -- There is no Rule #6.