in reply to Coding Perl With Style

Anecdotal testimony: this is only a passive endorsement.

Most of the projects I've been on, including the current one what we've done for variables that really need to be accessed from everywhere is first invent a unique namespace for the client. For example, "JacksLumber" Then we create a JacksLumber.pm and in there put all of the global variables we're gonna need as package variables (excused from strict with use vars).

The modules then go under the JacksLumber directory with names like JacksLumber/Tags.pm, JacksLumber/Security.pm, JacksLumber/LnF.pm, etc...

Within the main script "global" values are always accessed by the full package name. For example, $JacksLumber::basedir or $JacksLumber::appname. This has a few effects. First, it doesn't pollute the namespace of the script (like an import might do). Secondly, it makes "global" things stand out (yeah they're lengthy, but you shouldn't be typing them often anyway). Thirdly, we don't have to introduce unnecessary OO complications or encapsulation overkill for things that might not need it. (Although we do have a lot of OO and encap. in other places where it is needed.)

Replies are listed 'Best First'.
Re: Re: Coding Perl With Style
by Fastolfe (Vicar) on Nov 28, 2001 at 01:12 UTC

    I personally like this approach. It also lets application developers using your module do something like this:

    use JacksLumber; $JacksLumber::basedir = '/some/other/dir'; # override default

    This is simple and intuitive and avoids having the user of your module learn your configuration interface if he wants to make changes to these simple variables.

    HOWEVER, what if your configuration is complex? What if it's structured? What if you can't predict what the variable names will be while you're coding? You don't want to pollute your module's namespace with an unknown list of variables, so you gotta go with a hash (and perhaps a complex data structure).

    I've used a few different approaches, depending on the project. I've exported a %CONFIG hash (or a hashref), I've created an AUTOLOAD in a ::Config module that let me reference configuration as JacksLumber::Config->key and other things. I still haven't come across a technique that I liked that was well-suited to any project, and invariably I start with a simple approach that ends up more complicated, making my configuration approach too constraining. For example, if 'dir' was a variable under a 'base' hierarchy, I'd end up with something unmaintainable like JacksLumber::Config->base->{dir}. How intuitive is that? With the use of things like Class::Struct and similar modules, you might be able to make that a little more readable, but it's still ugly in my eyes.

    If your "global" variables might change between invocations of your package methods/functions, you might consider wrapping your configuration in an object, and set up object methods (or a generic 'get'/'set' pair) to allow you to set/fetch your "global" variables. In other words:

    # Go from this: use JacksLumber 'some_func'; $one = some_func(1, 2, 3); $JacksLumber::alternate_behavior = 1; $two = some_func(1, 2, 3); # To this: use JacksLumber; my $normal = new JacksLumber; my $alt = new JacksLumber(alternate_behavior => 1); $normal->some_func(1, 2, 3); $alt->some_func(1, 2, 3);

    But generally, the simplest thing to do might just be a hash or a hashref in your module's root namespace for complex configuration, or just some package variables if you can get by with that.

    Just my two cents...