in reply to Top level my vars and their global use in a file

Strictly speaking, file-scoped lexicals (my variables declared outside of a block) aren't globals. They can be dangerous all the same. They'll work fine. However, in longer programs, they can make things difficult to debug. If I have a couple of subroutines

use strict; my $id = 24601; sub foo { # .. lotsa code print "ID number is", $id, "\n"; # .. more code } sub bar { if ($id = 3) { # Oops-- I've accidentally set $id to 3 # do something subtle } }
If ID isn't supposed to be 3, I'll stare at the code for foo() for hours trying to figure out what's wrong with it, since that's where the odd value got printed out. Plus, the malfunction will only occur if I first call bar(), then foo(). Once something done in one subroutine can invisibly affect the outcome of another, then the predictability of what my program does has just dropped tremendously. When my program does something I can't predict, that's generally a bug.

If I pass $id as an argument, though, I'm stating explicitly that the actions and results of foo() are dependent on the value of $id. Also, common idiom will keep me from changing the value of my arguments unless I explicitly document otherwise.

If I use $id absolutely everywhere, and it's getting really irritating passing it around all over the place, at least put it behind some get-set routines. That will limit its scope and enable you to control how it is set, and make access stand out in the program. For example:

BEGIN { my $id = 24601; sub get_id { return $id; } sub set_id { my ($new_val) = @_; $id = $new_val; } } sub foo { # .. lotsa code print "ID number is ", get_id(), "\n"; # .. still more code }

Some will say that file-scoped lexicals are less of a problem on smaller programs. I mostly agree, except that small programs have an astonishing ability to become large programs, and their code quality rarely improves on the way.

I find package variables less dangerous than file-scoped lexicals, simply because one is disposed to declare them at the top of the program with use vars(). Better yet, if the "variable" isn't supposed to vary, use use constant instead. If you do use them, document that use in each subroutine that uses it, and declare each file-scoped lexical at the top of the file with a comment saying what it is.

So, in summary, I'd avoid worrying about the "politeness" of it. :) Instead, I'd avoid using file-scoped lexicals because it makes your life easier.

stephen

Note: Code in this node is not tested, since it's primarily conceptual.