File handles are traditionally package variables that represent file descriptors. Unlike other variables, file handles are typically not prefixed with punctuation. All barewords are subject to being interpreted by the parser differently than the developer intended, but bareword file handles are particularly fraught with peril. Consequently, file handles should never be stored as barewords.
Noncompliant Code Example
Suppose we maintain some simple code that makes the mistake of using bareword file handles.
This code works as expected. It reads and prints a line of good text, followed by a line of bad text, followed by a second line of good text.
But during maintenance, someone (undoubtedly with the best of intentions) adds this function:
This function completely changes the behavior of the subsequent code. The
BAD bareword is now interpreted as a subroutine call, not a file handle.
The program, as before, first opens
good.txt, storing it in the
GOOD file handle, which is a package variable. It next opens
bad.txt, but instead of storing the descriptor in a
BAD file handle, it stores the descriptor in the file handle returned by the
BAD() subroutine, which returns
GOOD. Consequently, the
GOOD file handle now points to the descriptor for
The program then tries to read from the
BAD file handle, but this attempted read produces nothing because this file handle was never actually opened. Nonetheless, the program then reads a line from the
GOOD file handle and echoes it—which turns out to be from
bad.txt rather than
This compliant solution protects the file descriptors by using anonymous scalars rather than bareword file handles.
Consequently, the original behavior of this program is restored. Because the
$BAD variable is declared with
my, it is a lexical variable rather than a package variable and is unaffected by the
BAD subroutine. So this program once again prints two lines from the
good.txt file and one from the
bad.txt file, and never confuses the two.
FIO00:EX0: The following barewords are built-in to Perl and are exceptions to this rule:
|[Conway 2005]||"Filehandles," p. 202|
|[CPAN]||Jeffrey Thalhammer, Perl-Critic-1.118, InputOutput::ProhibitBarewordFileHandles|
|[Wall 2011]||perlfunc, perlvar|