"... provide a namespace that was not package-level to prevent accidental use of "global" variables."

I use anonymous namespaces for this. I use them often. They can be nested to an arbitrary depth. Here's a (highly contrived) example:

my $global; { my $local_outer; # $global known here # $local_outer known here # $local_inner unknown here { my $local_inner; # $global known here # $local_outer known here # $local_inner known here } # $global known here # $local_outer known here # $local_inner unknown here # An entirely different $local_inner: my $local_inner; } # $global known here # $local_outer unknown here # $local_inner unknown here # An entirely different $local_outer: my $local_outer; # An entirely different $local_inner: my $local_inner;

Beyond avoiding all the issues with global variables, there's addition benefits. When an anonymous block is exited, the lexical variables declared within it, go out of scope and can be garbage collected. Also, if those variables were filehandles, Perl automatically closes them for you. Another contrived example:

{ open my $fh, '<', $filename; # ... read and process file contents here ... # As soon as the closing brace is reached: # 1) $fh goes out of scope - available for garbage collection # 2) an automatic "close $fh" is performed }
"In practice I have no idea how useful this is and how often that mistake occurs."

This is very useful, and a practice I recommend using as a default coding technique. It's very often the case that scripts, that start off being very short (e.g. a couple of dozen lines), are enhanced and extended and can end up with hundreds of lines. It's at this point that problems with global variables become apparent: you switch to debugging mode and start changing multiple $text variables, for instance, to $xxx_text, $yyy_text, and so on; then start the test/edit cycle, changing the $text variables missed on previous iterations, fixing incorrect renaming (s/$yyy_text/$xxx_text/) or typos (s/$xxxtext/$xxx_text/), and so on.

This sort of problem does seem very common. We get lots of "What's wrong with my code?" questions where scoping is the underlying cause.

Although I've focussed on anonymous namespaces here; the underlying objective is to use lexical variables in the smallest scope possible: that scope could also be provided by, for example, subroutine definitions and BEGIN blocks.

— Ken


In reply to Re^3: Using guards for script execution? by kcott
in thread Using guards for script execution? by R0b0t1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.