Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^2: lexical vs. local file handles

by jo37 (Deacon)
on Apr 18, 2020 at 19:40 UTC ( [id://11115736]=note: print w/replies, xml ) Need Help??


in reply to Re: lexical vs. local file handles
in thread lexical vs. local file handles

Hi haukex

thank you for your comments. I'm not fully convinced yet, though.

When you localize a glob, you're localizing every variable with that name - scalars, arrays, hashes, etc.
Sure. But I can keep a reference to those if needed. Or I can choose a different name for the file handle.
local's effects have dynamic scope, so they effect everything called in that scope, including code that might not be yours. You might step on someone else's globals, or they might step on yours. The major issue is that this is action at a distance: things may break in remote pieces of code, and it may be incredibly hard to connect the problem to the cause. This will not happen with lexicals.
As shown in my example, the usage in another package does no harm.
Bareword filehandles also clash with package names (see also).
Is this an issue occuring in real life? Probably I do not understand this in all detail yet.

Still using barewords :-)

Greetings,
-jo

$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

Replies are listed 'Best First'.
Re^3: lexical vs. local file handles
by haukex (Archbishop) on Apr 18, 2020 at 19:46 UTC

    It's probably possible to make localized bareword filehandles work, if you take a whole lot of care to avoid all the issues. But then again, you could be spending all that care on avoiding print $fh, "", couldn't you? (You could probably even write a Perl::Critic policy to avoid it - Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles already exists.) I guess I should have worded my point above as a question:

    Other than catching the print FH, "" issue, what advantages to using bareword filehandles do you see over lexical filehandles?

    Edit: Added link to module.

      My point is: bareword filehandles are something special in Perl syntactically. Avoiding them cuts off a part of the language.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

        You could say the same thing about goto and mutable global variables and even $[ (which, fortunately, is gone in newer language releases), but in general the same reason to avoid them applies: because using them makes it more difficult to reason about code in the small and the large.


        Improve your skills with Modern Perl: the free book.

        My point is: bareword filehandles are something special in Perl syntactically. Avoiding them cuts off a part of the language.

        Ok, but that wasn't my question...

Re^3: lexical vs. local file handles
by haukex (Archbishop) on Apr 18, 2020 at 21:49 UTC
    I'm not fully convinced yet, though.

    Here's one more: open local *HMD, ">", \(my $x) or die $!; print HND "Foo"; close HND; only causes warnings, while open my $hmd, ">", \(my $x) or die $!; print $hnd "Foo"; close $hnd; is a compile-time error. Warnings are easily missed in server logs or long command-line outputs.

    Sure. But I can keep a reference to those if needed. Or I can choose a different name for the file handle.

    Taken all together, doesn't it all seem to be getting a bit complicated? You've got quite a long list of things you need to keep track of: in the entire scope of the local (which you have to put in its own block to limit its scope), that is, the entire call stack, you have to know all of the names of the globs and packages that you're working with, and you have to be sure they don't clash with each other or anything else (your sub close_fh is just one example), plus you have to keep track of possible typos. None of these are things to worry about when you use lexical filehandles.

    Is all that really worth it to avoid the print $fh, typo? (If you're only ever going to be writing short command-line scripts that don't write much to STDOUT/ERR or call anyone else's code, maybe yes...?)

      Nitpicking on the HMD/HND example: It gives a compile time error, too.

      I haven't answered your question about the "why" yet.

      There is this special member of the Perl ecosphere called filehandle. It is special, it needs to be treated special and it is eye-catching. Beneath scalars, arrays, hashes and subs it is something "primal" in Perl. I just like filehandles and I thought they were there to be used.

      OTOH, reflecting all your points makes me thoughtful. Using the idiom given by Your Mother in Re: lexical vs. local file handles solves the one case where a bareword seemed to be of advantage.

      I really should abandon this habit. Thanks for your input and your patience.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

        Thanks for your reply. I very much like TIMTOWTDI, but I also like best practices (see also Tim Toady Bicarbonate). As I said, for small pieces of code that you have complete control over, you probably won't run into any of the described issues. But as an application grows, I imagine it would be harder and harder to keep track of all the potential issues.

        Nitpicking on the HMD/HND example: It gives a compile time error, too.

        Nope, I tested before posting :-)

        $ perl -wMstrict -le 'open local *HMD, ">", \(my $x) or die $!; print HND "Foo"; close HND; print "Done"'; echo $? Name "main::HMD" used only once: possible typo at -e line 1. print() on unopened filehandle HND at -e line 2. Done 0 $ perl -wMstrict -le 'open my $hmd, ">", \(my $x) or die $!; print $hnd "Foo"; close $hnd; print "Done"'; echo $? Global symbol "$hnd" requires explicit package name (did you forget to + declare "my $hnd"?) at -e line 2. Global symbol "$hnd" requires explicit package name (did you forget to + declare "my $hnd"?) at -e line 2. Execution of -e aborted due to compilation errors. 255

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-24 03:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found