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


in reply to Closing and re-opening the DATA Filehandle

Ugly hack:

my $pos= tell(DATA); chomp( my $x= <DATA> ); warn "Testing($x)"; { my $fh= do { local(*FH); \*FH }; open $fh, "<&DATA" or die "Can't save DATA: $!\n"; close DATA or warn "Can't close DATA: $!\n"; open DATA, "<&=".fileno($fh) or die "Can't restore DATA: $!\n"; seek DATA, $pos, 0 or die "Can't reposition DATA: $!\n"; } warn "Testing"; chomp( $x= <DATA> ); warn "Testing($x)"; __END__ some data
produces
Testing(some data) at redata.pl line 4, <DATA> line 1. Testing at redata.pl line 12. Testing(some data) at redata.pl line 14, <DATA> line 1.
which is what you asked for but needs some serious encapsulation work at least.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: Closing and re-opening the DATA Filehandle
by Adam (Vicar) on Apr 05, 2001 at 01:21 UTC
    Nope. That doesn't work either. I wrapped your code into a sub, so I could call it multiple times and got:
    Testing(some data) at D:\test.pl line 5, <DATA> line 1. Testing at D:\test.pl line 13. Testing(some data) at D:\test.pl line 5, <DATA> line 1. Can't save DATA: Bad file descriptor
    Here is test.pl:
    sub Tye { my $pos= tell(DATA); chomp( my $x= <DATA> ); warn "Testing($x)"; { my $fh= do { local(*FH); \*FH }; open $fh, "<&DATA" or die "Can't save DATA: $!\n"; close DATA or warn "Can't close DATA: $!\n"; open DATA, "<&=".fileno($fh) or die "Can't restore DATA: $!\n"; seek DATA, $pos, 0 or die "Can't reposition DATA: $!\n"; } warn "Testing"; } Tye(); Tye(); __END__ some data

      My mistake. I know this doesn't matter since you found a better solution but this bugged me and I found my mistake.

      I was thinking that the "=" in "<&=" was required when using a numeric file descriptor. But the "=" requests an fdopen() instead of a dup(), that is, the new file handle ends up sharing the same file descriptor with the old file handle. So when $fh is closed (triggered when it goes out of scope and gets destroyed), the file descriptor that DATA is using also gets closed out from under it.

      So just drop the "=" and my code works.

              - tye (but my friends call me "Tye")