Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

How can I make a filehandle local to a subroutine? How do I pass filehandles between subroutines? How do I make an array of filehandles?

by faq_monk (Initiate)
on Oct 08, 1999 at 00:23 UTC ( #649=perlfaq nodetype: print w/replies, xml ) Need Help??

Current Perl documentation can be found at

Here is our local, out-dated (pre-5.6) version:

The fastest, simplest, and most direct way is to localize the typeglob of the filehandle in question:

    local *TmpHandle;

Typeglobs are fast (especially compared with the alternatives) and reasonably easy to use, but they also have one subtle drawback. If you had, for example, a function named TmpHandle(), or a variable named %TmpHandle, you just hid it from yourself.

    sub findme {
        local *HostFile;
        open(HostFile, "</etc/hosts") or die "no /etc/hosts: $!";
        local $_;               # <- VERY IMPORTANT
        while (<HostFile>) {
            print if /\b127\.(0\.0\.)?1\b/;
        # *HostFile automatically closes/disappears here

Here's how to use this in a loop to open and store a bunch of filehandles. We'll use as values of the hash an ordered pair to make it easy to sort the hash in insertion order.

    @names = qw(motd termcap passwd hosts);
    my $i = 0;
    foreach $filename (@names) {
        local *FH;
        open(FH, "/etc/$filename") || die "$filename: $!";
        $file{$filename} = [ $i++, *FH ];

    # Using the filehandles in the array
    foreach $name (sort { $file{$a}[0] <=> $file{$b}[0] } keys %file) {
        my $fh = $file{$name}[1];
        my $line = <$fh>;
        print "$name $. $line";

For passing filehandles to functions, the easiest way is to prefer them with a star, as in func(*STDIN). See Passing Filehandles for details.

If you want to create many, anonymous handles, you should check out the Symbol, FileHandle, or IO::Handle (etc.) modules. Here's the equivalent code with Symbol::gensym, which is reasonably light-weight:

    foreach $filename (@names) {
        use Symbol;
        my $fh = gensym();
        open($fh, "/etc/$filename") || die "open /etc/$filename: $!";
        $file{$filename} = [ $i++, $fh ];

Or here using the semi-object-oriented FileHandle, which certainly isn't light-weight:

    use FileHandle;

    foreach $filename (@names) {
        my $fh = FileHandle->new("/etc/$filename") or die "$filename: $!";
        $file{$filename} = [ $i++, $fh ];

Please understand that whether the filehandle happens to be a (probably localized) typeglob or an anonymous handle from one of the modules, in no way affects the bizarre rules for managing indirect handles. See the next question.

Log In?

What's my password?
Create A New User
marioroy At a large firm, had to awaken a security guy a few times so that nobody would catch him sleeping.
marioroy On a large dairy farm, almost went off the road with a 10 wheeler from exhaustion. On the farm, almost went off the silo with a big tractor. At the Fransiscan monastery, almost slipped off the dome while painting it.
[marioroy]: In Saudi Arabia caught fire but didn't burn. I think angels exist.
Lady_Aleena clean up after dinner finally.
[Discipulus]: uch! so we are twice lucky to have MCE..;=)
[marioroy]: Working a midnight graveyard shift, on the way home ran out of gas. just 2 minutes later somebody stops with a small tank of gas. It's wierd. There's always someone nearby for some reason.
[Lady_Aleena]: I was the one who stop[ed in the middle of a cold night to pick up a small family walking to a gas station. I got a few gallons of free gas for the round trip, and the grandmother said she'd pray for me.
[marioroy]: Folks do not know it, but MCE was ridiculously difficult. At Niagra Falls, heard a voice on enabling Grace while in the mist boat. That 10x performance is possible.

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2017-05-29 08:24 GMT
Find Nodes?
    Voting Booth?