I will just agree to disagree and carry on.
If you don't feel like continuing the discussion, that's fine with
me. I actually did think a fair bit about whether to respond, but in
the end I did want to complete my list of arguments for lexical
filehandles so that this thread might be a useful collection of such
arguments for others as well.
I am also left wondering a bit what exactly you disagree with.
That you will continue to use them? That's fine with me, as I said
early on. That bareword filehandles shouldn't be recommended to
newcomers? I still believe that and have provided plenty of
arguments. That there is no functional difference? I feel like I've
shown this isn't true. Anyway, on to the other points:
A lexical file handle declared at top-level only goes
out of scope at the end of the script, just like a bareword file
handle.
Right, that's true, and yes, part of my argument was for a broader
case. Much of what I've said applies no matter the scope of the
filehandles.
We have gone way off into the weeds and have now
talked past each other.
I feel like I've been responding to nearly every one of the points
you made. But to re-focus, your initial post was:
... I will quibble with ["the preferred style is
to use a scalar variable for a file handle"] at top-level as in
this case: there is no functional difference between the lexical file
handles in your example and the traditional global file handles — in
both cases, a handle opened at top-level is defined until the end of
the script and valid until closed. Please correct me if I am somehow
misinformed about this.
I've already given plenty of examples of how "there is no
functional difference between the lexical file handles in your
example and the traditional global file handles" isn't true -
unless by "functional" you really just mean "it works", to
which I'd say that code using bareword filehandles can stop working
much more easily than code using lexical filehandles, and I've named
examples of how that can happen (name collisions etc.).
As for the specific "in both cases, a handle opened at
top-level is defined until the end of the script and valid until
closed", a nitpicky response to that is that a lexical filehandle
can simply be assigned to, as in $fh = undef;, to undefine it,
close it, and cause fatal errors in case one attempts to use it
again, but I haven't yet found an equivalent for bareword
handles.
The closest I've found so far is
use Symbol qw/geniosym/; *FH = geniosym; (thanks to
Discipulus for pointing this out), which closes the underlying
filehandle, but aside from being cumbersome to say, afterwards
print FOO ... will only cause a warning, not an error, which I
think is a serious drawback. Other methods, like
undef *FH, *FH = *DUMMY, or
*FH = do { local *HANDLE; \*HANDLE } have the major
disadvantage that they affect every package variable with the
name FH, as in $FH, @FH, %FH, etc. Maybe
another Monk knows if there's a real equivalent (it's probably
possible with XS), but for now, I have my doubts.
Another thing to nitpick is that often, code examples posted here
are SSCCE's, i.e. the asker has taken code out of a
sub and used it at the top level, or someone answering the
question is showing a much simplified example where the code is in
the file scope, but the code is actually intended to go into a
sub somewhere. Since you've said yourself you think bareword
filehandles are incorrect in this case, this means that everyone who
sees bareword filehandles would have to know and remember to
rewrite the bareword filehandles into lexical ones when refactoring
code from the top level into a sub. Just using lexicals
everywhere seems a much easier solution.
Sorry, but I don't really see what arguments for bareword
filehandles are left, other than making newcomers to the language
aware of the fact that they exist but are not a best
practice.
And again, all this is not to say that I hate them or they should
"never, ever" be used. Bareword filehandles are definitely something
that make Perl interesting; for example in the one-argument
open:
our $FH = "input.txt";
open FH or die $!; # opens input.txt !
But there's a huge difference between writing "interesting" code,
which I do enjoy, and writing modern, robust, well-maintainable
applications.
Update:
I don't think it's been referenced in this thread yet, but of course
TheDamian's Perl Best Practices
has several pages of arguments at the beginning of Chapter 10 (I/O) against
bareword filehandles and for lexical ones ("indirect filehandles"),
and there's the corresponding Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles
(defaulting to the highest severity),
and chromatic's Modern Perl
also names them
in the chapter "What to Avoid". | [reply] [Watch: Dir/Any] [d/l] [select] |