http://qs321.pair.com?node_id=11118779


in reply to Is there a problem with using barewords as filehandles ?

Bareword filehandles have their places, particularly in simple scripts, where there really is almost no difference between them and lexical file handles — declaring a lexical at file-scope has almost exactly the same effect, and exactly the same effect if the convention of maintaining a 1:1 mapping between files and packages is followed.

However, a sub that opens a file and returns a handle should always return a lexical filehandle, unless its purpose is to return "THE" singleton filehandle for some resource, and in that case it should be using our to store the filehandle in a global. Generally, bareword filehandles should be limited to the mainline code in the top-level script. Subroutines should use lexical filehandles and modules should only contain subroutines.

In Perl, all "globals" are actually package variables, although a few special names (including the "punctuation variables") are forced into package main. The distinction is that a "global" variable is stored in a symbol table slot in some package. Package variables in Perl are globally-accessible, since the package namespace is itself global. The our keyword creates lexically-scoped aliases to package variables and is very convenient when needed.

A lexical declared at file scope is effectively a global variable and has all of the same problems in complex code, with the additional risk that file-scope lexicals can be shared across packages if multiple packages are defined in the same file. Global variables are generally dangerous in programming and I strongly favor the use of bareword filehandles at top-level in preference to declaring lexicals at file-scope and thinking that you are safe.

Perhaps the best would be to default to use bareword::filehandles in package main and no bareword::filehandles in other packages. This keeps the feature where it is most useful, to avoid the "head in sand" problem of using file-scope lexicals in the main script, while still pushing modules to avoid the feature unless it really is appropriate.