The Perl Basics You Need To Know Page 3
Now in packages that want to use the configuration variables I have either
to use the fully qualified names like ::Config::test, which I
dislike or import them as described in the previous section. But hey, since I
have only one variable to handle, I can make things even simpler and save the
loading of the Exporter.pmpackage. I will use the Perl aliasing
feature for exporting and saving the keystrokes:
package My::HTML;
use strict;
use lib qw(.);
# Global Configuration now aliased to global %c
use My::Config (); # My/Config.pm in the same dir as script.pl
use vars qw(%c);
*c = \%My::Config::c;
# Now you can access the variables from the My::Config
print {scalar_var};
print {array_var}[0];
print {hash_var}{foo};
Of course is global everywhere you use it as described
above, and if you change it somewhere it will affect any other packages you
have aliased ::Config::c to.
Note that aliases work either with global or local() vars--you
cannot write:
my *c = \%My::Config::c; # ERROR!
Which is an error. But you can write:
local *c = \%My::Config::c;
For more information about aliasing, refer to the Camel book, second edition, pages 51-52.
Using Non-Hardcoded Configuration Module Names
You have just seen how to use a configuration module for configuration centralization and an easy access to the information stored in this module. However, there is somewhat of a chicken-and-egg problem--how to let your other modules know the name of this file? Hardcoding the name is brittle--if you have only a single project it should be fine, but if you have more projects which use different configurations and you will want to reuse their code you will have to find all instances of the hardcoded name and replace it.
Another solution could be to have the same name for a configuration module,
like My::Config but putting a different copy of it into different
locations. But this won't work under mod_perl because of the namespace
collision. You cannot load different modules which uses the same name, only the
first one will be loaded.
Luckily, there is another solution which allows us to stay flexible.
PerlSetVar comes to rescue. Just like with environment variables,
you can set server's global Perl variables which can be retrieved from any
module and script. Those statements are placed into the httpd.conf
file. For example:
PerlSetVar FooBaseDir /home/httpd/foo PerlSetVar FooConfigModule Foo::ConfigNow I
require()the file where the above configuration will be used:PerlRequire /home/httpd/perl/startup.plIn the
startup.plI might have the following code:# retrieve the configuration module path use Apache: my = Apache->server; my = ->dir_config('FooBaseDir') || ''; my = ->dir_config('FooConfigModule') || ''; die "FooBaseDir and FooConfigModule aren't set in httpd.conf" unless and ; # build the real path to the config module my = "/"; =~ s|::|/|; .= ".pm"; # I have something like "/home/httpd/foo/Foo/Config.pm" # now I can pull in the configuration module require ;
