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::Config

Now I require() the file where the above configuration will be used:

  PerlRequire /home/httpd/perl/startup.pl

In the startup.pl I 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 ;

This article was originally published on Aug 2, 2000

Thanks for your registration, follow us on our social networks to keep up-to-date