File handles

Whenever we need to deal with reading and writing to files in Perl, we use
a file handle. In order to get a file handle for a file, we need to open
that file using open. Traditionally file handles are presented as
bare words in all upper-case:

Bare word file handles exist on a package basis, starting from where the file is
opened until the file is closed or the program exits. Attempting to open
another file to a file handle of the same name will close the existing file handle
before re-opening it to the new file. When this occurs in a subroutine you call
while processing your file contents you can end up with a bug which is hard to
track down. This is one example of ``action from a distance''.

Fortunately, in Perl 5.6.0 and above, we can also use scalar file handles when
opening files. These file handles can be given a lexical scope by using the
my keyword, just like any other Perl scalar.

Scalar file handles are easily passed to subroutines or stored in data
structures. Further, when they go out of scope the file is closed. This
prevents many of the ``action from a distance'' problems that may occur with
the traditional file handles, and can also help reduce the number of files
needlessly left open.

Printing to file handles

When printing to a file there is no comma in between the file handle and the
arguments to be printed. However adding the comma is an easy mistake to make,
and often a very hard bug to spot:

# This does not print to the OUT file handle
print OUT, $line, $sep, $_;
# This does not print to the $out file handle
print $out, $line, $sep, $_;

The lack of a comma between the file handle and the list of things to print,
allows Perl to recognise the file handle as something special. This is
called an indirect argument and is similar to the optional code block in
sort, grep and map. Unfortunately the comma is so small that it
can be hard for us to use to recognise that we've added it. Worse still,
another programmer (or ourselves in six months time) may inadvertently insert
the comma at a later date, believing the original statement to be incorrect or
``strange''.

A good solution is for us to make the file handle more prominent.
Capitalised bare words provide this, but have drawbacks as mentioned above.
An excellent alternative, examined by Dr Damian Conway in his ``Perl Best
Practices'' book, is to add curly braces around the file handle.

Just like sort, grep and map we now know that if these curly
braces are followed by a comma, we've made a mistake. The braces also make it
very clear, even to a novice programmer, that {$out} is something special,
and not just another variable to be printed.

Adopting a naming convention where all file handles end in _fh can also make
it more obvious when they are being misused. $config_fh is obviously a
configuration file handle, whereas $config may not be.