www.socialtext.net will be down for scheduled maintenance today Sat July 31st starting at 6:00pm PDT (Sun August 1st 1:00am UTC). Estimated downtime is 20 minutes, please contact support@socialtext.com with any questions.

Bareword uppercase filehandles

hide

FILEHANDLEs 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

readline $fh

print OUT "foo";
print {OUT} "foo";

print $fh "foo";
print {$fh} "foo";

FH->autoflush(1) $fh->autoflush(1)

foo(FH); # bad: bareword string
foo(*FH);
foo(\*FH);

foo($fh)

Tags

    There are no tags for this page.

Attachments

Created by site perlwiki on May 19 2:16pm. Updated by glauschwuffel on Jun 2 7:32am. (5 revisions, 2,899 views)