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

Occasionally I see in scripts other people write, the idiom

local (*FILE)

where FILE is the filehandle being initialized. The question is, why do this? I always just create my filehandles when I need them, by assigning them names in my open(FILE,"$file") statements. Is there a really good reason to initialize them ahead of time with local?

Replies are listed 'Best First'.
Re: Local(*FILE);
by CheeseLord (Deacon) on Jan 13, 2002 at 01:35 UTC

    That's not an initialization - that's keeping the FILE I'm working with from affecting any other FILE filehandles in the program. For example:

    use Fatal qw( open ); # Because I'm lazy open FILE, "one"; print scalar(<FILE>); { local *FILE; open FILE, "two"; print <FILE>; close FILE; } print <FILE>; close FILE;

    That will print out the first line of one, then all of two, and then the rest of one.

    Note: A lot more explanation of this same usage can be found by checking out local.

    His Royal Cheeziness

Re: Local(*FILE);
by dws (Chancellor) on Jan 13, 2002 at 01:49 UTC
    Before the advent of IO::File, which provides an object-oriented API for accessing files, there was no alternative to using file handles. The problem with file handles come when writing (or using) modules. If a routine in a module needs to open a file, and uses FILE for the file handle, the only way to avoid smashing some other FILE is to localize the file handle using the   local *FILE; idiom. This guarantees that any other variables named FILE will be restored at the end of the routine that does the localizing.

    If you're writing a simple script, there's little reason to do this yourself. If you're writing a module, the better thing to do now is use IO::File for file access.

Re: Local(*FILE);
by clintp (Curate) on Jan 13, 2002 at 02:05 UTC
    As others pointed out, it's not an initialization and serves to protect the filehandle from stomping on other filehandles of the same name (in the surrounding scope).

    Additionally it has another effect: when you leave that scope the filehandle is closed automagically:

    use warnings; { local *T; open(T, ">foo") || die; print T "HALHGLAG\n"; # Works okay! } print T "Surprise!\n"; # warns "print() on closed file..."
Re: Local(*FILE);
by IlyaM (Parson) on Jan 13, 2002 at 06:54 UTC
    I want to add to all replies above that in new perls (5.6.0 and later) you can use my instead of local with filehandles in open.

    That is code like

    local *FILE; open FILE, $filename or die "Can't open file: $!"; my $data = <FILE>; close FILE;
    can be replaced with
    open my $file, $filename or die "Can't open file: $!"; my $data = <$file>; close $file;

    --
    Ilya Martynov (http://martynov.org/)

      As stated in perlstyle, it is very important that the debugging message includes all of the important information, including the filename. (And for those who think I sound like a broken record on this, spend a couple of hours late at night trying to figure out which file out of several thousand accessed by a script you have never seen broke the production run, and then tell me that insisting on having the filename is unreasonable...)

      A few incidental points. The first is that people seeking to slurp a file usually don't want just the first line. And secondly if you make a habit of scoping file handles tightly, there is no need to close them. Your preferences may vary, but I usually don't bother. And finally, as chip says, if you have the choice in 5.6.0+, it is better to use the 3-arg open. See Two-arg open() considered dangerous for details and discussion.

      sub slurp_file { my $file_name = shift; open(my $fh, "<", $file_name) or confess("Cannot read '$file_name': +$!"); wantarray ? <$fh> : join '', <$fh>; }

        A very hearty thanks to everyone who posted a response to my query. All were very informative!