Bareword uppercase filehandles
hideFILEHANDLEs without sigils are a sign of ancient Perl. This page aims to describe why this style was once common, what's wrong with it, and what you can do to fix up your legacy source code.
Typically, these old style filehandles are written in ALLCAPS. This is purely convention, there's no technical requirement for that. You may also find non-uppercase bareword filehandles, which can be even worse because they may be hard to spot.
History: global variables everywhere
Originally, and that's a very long time ago, Perl had only global variables. Every named scalar, array, hash, and filehandle had to be unique throughout the namespace. There are numerous dangers with global variables, but they're all some form of action at a distance.
Global filehandles live in a typeglob just like scalars and arrays, but they don't have a sigil. You could use the * sigil, that refers to the entire typeglob. In fact, this is how you create a reference to a package global filehandle: \*FILEHANDLE
Why it's bad now
Enter Perl 5, which brought the joy of lexical scope to Perl. Variables can now be local to a single block, and then even a single execution of that block. If the block is be executed twice because of recursion, each incarnation has its own set of lexical variables. Lexical variables, declared with my, can also be used as filehandles. This adds the many advantages of lexical scoping to filehandles, and is generally a very good idea. While internally, these are references to the same old typeglobs, you don't have to care about this if you let Perl create them for you. They're anonymous and unique.
Using a global where you could have used a lexical is bad, because the lexical variable is likely to prevent silly mistakes. Oh, and files are automatically closed as soon as their handle goes out of scope too!
Perl creates a filehandle automatically if you pass an undef value to a function like open. Because every variable begins its life undefined, that's a pretty easy thing to do!
Good uses of bareword filehandles
The three built-in filehandles STDIN, STDOUT, and STDERR are still written like that. Since there is always at most one of each, there's no harm in them being global. Actually, it comes in very handy.
Fixing your code
To improve your code, simply find all occurrences of bareword filehandles and add a $ sigil in front. At the first use, also add my to it, to declare the variable. And while you're at it, change the UPPERCASE back to lowercase. There's now a nice $ sigil that makes it stand out.
| Before | After |
| open FH, "<", "/etc/passwd" ... | open my $fh, "<", "/etc/passwd" ... |
| <FH> | <$fh> |
readline FH |
readline $fh |
print OUT "foo"; |
print $fh "foo"; |
| FH->autoflush(1) | $fh->autoflush(1) |
foo(FH); # bad: bareword string |
foo($fh) |