Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^12: Summing numbers in a file

by jcb (Parson)
on Jun 05, 2020 at 02:34 UTC ( [id://11117709]=note: print w/replies, xml ) Need Help??


in reply to Re^11: Summing numbers in a file
in thread Summing numbers in a file

One more might be that lexical filehandles are closed automatically when they go out of scope, but bareword filehandles are not (only when the script ends, which may be a lot later, depending on the code).

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. We have gone way off into the weeds and have now talked past each other. I will just agree to disagree and carry on.

Replies are listed 'Best First'.
Re^13: Summing numbers in a file (updated)
by haukex (Archbishop) on Jun 06, 2020 at 15:18 UTC
    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".

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11117709]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-29 01:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found