views:

221

answers:

2

Is there a standard way to code a module to hold global application parameters to be included in every other package? For instance: use Config;?

A simple package that only contains our variables? What about readonly variables?

+7  A: 

There's already a standard Config module, so choose a different name.

Say you have MyConfig.pm with the following contents:

package MyConfig;

our $Foo = "bar";

our %Baz = (quux => "potrzebie");

1;

Then other modules might use it as in

#! /usr/bin/perl

use warnings;
use strict;

use MyConfig;

print "Foo = $MyConfig::Foo\n";

print $MyConfig::Baz{quux}, "\n";

If you don't want to fully qualify the names, then use the standard Exporter module instead.

Add three lines to MyConfig.pm:

package MyConfig;

require Exporter;
our @ISA = qw/ Exporter /;
our @EXPORT = qw/ $Foo %Baz /;

our $Foo = "bar";

our %Baz = (quux => "potrzebie");

1;

Now the full package name is no longer necessary:

#! /usr/bin/perl

use warnings;
use strict;

use MyConfig;

print "Foo = $Foo\n";

print $Baz{quux}, "\n";

You could add a read-only scalar to MyConfig.pm with

our $READONLY;
*READONLY = \42;

This is documented in perlmod.

After adding it to @MyConfig::EXPORT, you might try

$READONLY = 3;

in a different module, but you'll get

Modification of a read-only value attempted at ./program line 12.

As an alternative, you could declare in MyConfig.pm constants using the constant module and then export those.

Greg Bacon
Rather than inheriting from `Exporter`, you can just grab its `import` method, which is all you really need. e.g. `use Exporter 'import';`
friedo
+4  A: 

Don't use global variables for configuration and don't sotre configuration as code. I have an entire chapter in Mastering Perl about this.

Instead, make a configuration class that any other package can use to access the configuration data. It will be much easier in the long run to provide an interface to something you may want to change later than deal with the nuttiness you lock yourself into by scattering variables names you have to support for the rest of your life.

A config interface also gives you the benefit of composing new answers to configuration questions by combining the right bits of actual configuration data. You hide all of that behind a method and the higher levels don't have to see how it's implemented. For instance,

 print "Hello!" unless $config->be_silent;

The be_silent answer can be triggered for multiple reasons the higher-level code doesn't need to know about. It could be from a user switch, that the program detected it is not interactive, and so on. It can also be flipped by options such as a debugging switch, which overrides all other preferences. No matter what you decide, that code line doesn't change because that statement only cares about the answer, not how you got the answer.

brian d foy