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


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

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...?)

Replies are listed 'Best First'.
Re^4: lexical vs. local file handles
by jo37 (Deacon) on Apr 19, 2020 at 07:52 UTC

    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

        This must have been some strange copy&paste mistake. I got an error, but afterwards re-used the source file. So the content is lost and I cannot reproduce it.

        If you hadn't convinced me before, this would.

        Greetings,
        -jo

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