lpoht has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm starting to get seriously involved in perl, and am wondering how some of the more experienced programmers approach this issue. I write scripts primarily for CGI and web applications, and need to make them portable. Right now, I use environment variables to point to the directory for packages, directory for logs, and directory for config files. The problem I keep running in to with using environment variables is that on windows systems, the computer must be rebooted for system variables to be re-loaded from the registry. Thus, if one wants to move the log directory on a live server, he would have to change the environment variable then reboot. Because I must make my scripts portable, I cannot use the Windows registry to store this information. How do you guys load your configs? Thanks.
  • Comment on How do you load configuration variables

Replies are listed 'Best First'.
Re: How do you load configuration variables
by sauoq (Abbot) on Jul 13, 2003 at 20:47 UTC

    Hardcode¹ the path to a config file and put everything you need in there.

    1. Don't hardcode it more than once though... use a constant or global variable near the beginning of your program where it will be easy to find.

    "My two cents aren't worth a dime.";

      I always create a module to handle program configuration, and I always call it Program::RC

      Then Program::RC has a method new that instantiates an object that reads the configuration from whereever it is stored (config file, la windows INI file is pretty good, with permissions well set so as to protect sensitive data), database, LDAP directory, whatever.

      The class offers a series of methods to access the different parts of the configuration file and give the variables values.

      This approach has one added advantage, each time you instantiate a configuration object, the config file is read, so you can change the configuration and test it on the fly, not even a SIGHUP is needed.

      An example:

      use Foo::RC; # prepare things ... # now fork if ( my $pid = fork() ) { my $ret = process_request( @ data ); # ... other hooks, or whatever } else { ... } sub process_request { # blah blah blah my $rc = new Foo::RC; my ($server_ip, $server_port, $bind_dn, $bind_passwd) = $rc->get_ldap_server_data; # ... }

      Each time the program has to process a request, it reads its configuration. Unless it's a huge config file, this is almost unnoticeable delay, and you can always memoize or create a cache for this system once it's production time (this is really useful to developing/debugging...)

      good luck,

      NB: as I usually use Net::Server to make these things, the fork code can be wrong, please forgive me...

      our $Perl6 is Fantastic;

        I always create a module to handle program configuration, and I always call it Program::RC

        Why not just write that module once, name it once, and then reuse it in each application? Better yet, why not just use a module that already exists for just such a purpose; something like AppConfig, for instance?

        No matter how you access your config file — AppConfig, a home-brewed module, do $config or die $!, whatever — it's still best to hardcode the path in your program and allow it to be overridden with command-line args or envariables as necessary.

        "My two cents aren't worth a dime.";
Re: How do you load configuration variables
by BrowserUk (Pope) on Jul 13, 2003 at 21:00 UTC

    You don't need to re-boot, only re-start the process (See Re: Re: Updating Microsoft Windows (win32) environment variables for a fuller explanation).

    However, that is probably equally inconvenient on a live system, so putting your configuration in a config file as sauoq suggested is probably better as well as more portable.

    Whether making changes to a live system is a 'Good Thing' is another matter, but that's between you, your clients and your backup system:)

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

Re: How do you load configuration variables
by l2kashe (Deacon) on Jul 14, 2003 at 04:00 UTC
    Personally I have become a big fan of config::general. Its pretty trim, provides methods for updating the data file on the fly, should be as portable as perl ( im guessing here. ).
    use Config::General; my $cfg_file = '/path/to/some/file'; my $cfg_obj = Config::General->new($cfg_file); my $href_config = $cfg_obj->get_all();
    You could even set up a signal handler for catching say sig USR1 or USR2. 1 for dumping the current config from memory to the filesystem, and the other for reloading the config from the filesystem.


    MMMMM... Chocolaty Perl Goodness.....
Re: How do you load configuration variables
by bugsbunny (Scribe) on Jul 14, 2003 at 08:33 UTC
    I'm using primary module for config variables etc.. like this..
    package SA::Config; use strict; BEGIN { require Exporter; @SA::Config::ISA = qw(Exporter); @SA::Config::EXPORT = qw(%c); } our %c = ( var1 => '/blah', logDir => '/var/log' ); 1;
    then in your scripts :
    use SA::Config qw(%c);
    This way i.e when storing as HASH u don't clutter the namespace and config variable usage is easy spotted.. Faster way can be also to place all your virables in file and then "require" them, but this has some disadvantages.. (One more thing i do is separate utilities functions into separate Utils.pm module..).
    Other thing that comes to my mind :") along these lines is to use different name spaces f.e. :
    Project1::Config Project2::Config ... etc..
    this way u can have common lib directory for all your projects w/o having problem between them..