http://www.perlmonks.org?node_id=258355


in reply to how can i use one handle for multifple files

Yep, you can keep a filehandle in a scalar at any time:

open my $fh1,'<', $file1 or die ...; open my $fh2,'<', $file2 or die ...; my $fh = $fh1; print $fh ...; if( some_condition ){ $fh = $fh2; } print $fh .... close $fh1; close $fh2;
--
http://fruiture.de

Replies are listed 'Best First'.
Re: how can i use one handle for multiple files
by hacker (Priest) on May 15, 2003 at 11:15 UTC
    The other benefit here, is that scalars can go out of scope, while file handles can't.. which can be very advantageous in some cases, because it provides for automatic cleanup so you don't have to close your filehandles explicitly in subs and blocks.
      File handles can go out of scope, if you use localized typeglobs.
      { local *FH; open FH, ">output.txt" or die "Can't write to file: $!"; print FH "Anything...\n"; printf STDERR "fileno for FH: %d\n", fileno(FH); } # ... open FH2, ">output2.txt" or die "Can't write to file: $!"; printf STDERR "fileno for FH2: %d\n", fileno(FH2);
      The file handle will be closed when the block is exited. It is extremely likely that you'll see the same value for fileno() for both handles... (for this as a script, I expect to see the value 3) indicating that the first one was released, thus, the handle got closed.
Re: Re: how can i use one handle for multifple files
by Skeeve (Parson) on May 15, 2003 at 11:37 UTC
    You can implify your code if you put your filehandles into a hash. The condition was a test for a word (TRUE or FALSE) so the hash would be:
    $fh{'TRUE'}=$fh1; $fh{'FALSE'}=$fh2;
    and the print woud simply be: print $fh{$test} "..." Update: Thanks to BrowserUK (see below)!
    print { $fh{$test} } "..."
      No, that will not work - You cannot print directly to a file handle stored in anything other than a scalar because of the typeglob nature of file handles. Your code would return the following error as a result of the hash entry being interpreted as the first element of a list argument to the print function:

      String found where operator expected at test.perl line 10, near "} "te +st\n"" (Missing operator before "test\n"?) syntax error at test.perl line 10, near "} "test\n"" Execution of test.perl aborted due to compilation errors.

       

      perl -le 'print+unpack("N",pack("B32","00000000000000000000001001011001"))'

        This can be worked around by wrapping your lexical file handles with curlies print {$fh} 'Stuff to print';

        Eg.

        D:\Perl\test>type temp2.pl8 #! perl -slw use strict; my @handles; open $handles[$_], '>', "test$_.dat" for 0 .. 3; print {$handles[$_]} 'Some text' for 0 .. 3; for( @handles ) { print {$_} 'Some more text'; } D:\Perl\test>temp2.pl8 D:\Perl\test>type test*.dat test0.dat Some text Some more text test1.dat Some text Some more text test2.dat Some text Some more text test3.dat Some text Some more text

        You can also use this to store your file handles in a hash which can be useful. You can even use an anonymous block to determine which handle to use at runtime. From perlfunc:print (>5.6?)

        Note that if you're storing FILEHANDLES in an array or other expressio +n, you will have to use a block returning its value instead: print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller