Previous Page
Next Page

10.2. Indirect Filehandles

Use indirect filehandles.

Indirect filehandles provide a much cleaner and less error-prone alternative to bareword filehandles, and from Perl 5.6 onwards they're as easy to use as barewords. Whenever you call open with an undefined scalar variable as its first argument, open creates an anonymous filehandle (i.e., one that isn't stored in any symbol table), opens it, and puts a reference to it in the scalar variable you passed.

So you can open a file and store the resulting filehandle in a lexical variable, all in one statement, like so:

    open my $FILE, '<', $filename
        or croak "Can't open '$filename': $OS_ERROR";

The my $FILE embedded in the open statement first declares a new lexical variable in the current scope. That variable is created in an undefined state, so the open fills it with a reference to the filehandle it's just created, as described earlier.

Under versions of Perl prior to 5.6, open isn't able to create the necessary filehandle automatically, so you have to do it yourself, using the gensym( ) subroutine from the standard Symbol module:

    use Symbol qw( gensym );

# and later...
my $FILE = gensym( ); open $FILE, '<', $filename or croak "Can't open '$filename': $OS_ERROR";

Either way, once the open filehandle is safely stored in the variable, you can read from it like so:

    $next_line = <$FILE>;

And now it doesn't matter that the name of that filehandle is $FILE (at least, not from the point of view of code robustness). Sure, it's still a lousy, lazy, unimaginative, uninformative name, but now it's a lousy, lazy, unimaginative, uninformative, lexical name, so it won't sabotage anyone else's lousy, lazy, unimaginative, uninformative name[*].

[*] Of course, it would be even better if you gave the variable a lucid, lyric, imaginative, informative name (see Chapter 2). But that may not be your forte: "Dammit, Jim, I'm a Perl hacker, not Walt Whitman!"

Even if there's already another $FILE variable in the same scope, the open won't clobber it; you'll merely get a warning:

    "my" variable $FILE masks earlier declaration in same scope

and the new $FILE will hide the old one until the end of its scope.

Apart from avoiding the perils of global namespaces and the confusion of barewords that are sometimes subroutine calls, lexical filehandles have yet another advantage: they close themselves automatically when their lexical variable goes out of scope.

This feature ensures that a filehandle doesn't accidentally outlive the scope in which it's opened, it doesn't unnecessarily consume system resources, and it's also less likely to lose unflushed output if the program terminates unexpectedly. Of course, it's still preferable to close filehandles explicitly (see the "Cleanup" guideline later in this chapter), but lexical filehandles still improve the robustness of your code even when you forget.

    Previous Page
    Next Page