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

Fearfully asking my first question at the Monastery:
Reading the various nodes on configuration files has prompted me to change my current config usage(primarily 'require'ing in files). I've decided to create a module to abstract my usage of XML-based config files. (If you're curious about why I am 're-inventing the wheel' in this way, I'll be glad to explain.)
I have two questions which I hope someone here can help me with. First, here is what I have so far:
package SiteConfig; use strict; use XML::Simple; BEGIN { use vars qw( @configs ); @configs = qw( site search survey editor ); } use vars qw( @ISA %EXPORT_TAGS @EXPORT_OK @EXPORT ); require Exporter; @ISA = qw(Exporter); %EXPORT_TAGS = ( ); @EXPORT = qw( ); @EXPORT_OK = map ('%'.$_, @configs2); # Config Starts Here use vars map ('%'.$_, @configs2); # Import config files %site = %{ XMLin('./site.xml') }; %search = %{ XMLin('./search.xml') }; %survey = %{ XMLin('./survey.xml') }; %editor = %{ XMLin('./editor.xml') }; 1;
My intent is to be able to use the module as follows:
use SiteConfig qw( %site %search );
importing in only the config hashes I need for that app. My first (and most important) question is: how do I do the final import section without explicitly listing each hash, and without using symbolic refs?
I know, for example, that I could do this:
no strict; for (@configs) { %{$_} = %{ XMLin("./$_.xml") }; }
but I also know that in most cases that is a taboo. Is there an alternative that will allow me to keep my clean and simple interface without resorting to evil?
Second question: It's obviously a waste of resources to import all of the XML files for an application that will only be using one or two config hashes. Is there someway to trick the module into only loading the files when I import the associated hash?

Thanks,
Impossible Robot

Replies are listed 'Best First'.
(tye)Re: Another config file module (any alternative to symbolic refs?)
by tye (Sage) on Oct 30, 2001 at 22:15 UTC

    For your first question:

    my( %site, %search ); use SiteConfig ( site=>\%site, search=>\%search );

    Update: Rereading your code, I suspect the above may not be enough information. (:

    package SiteConfig; use strict; use XML::Simple; sub import { my %toImport= @_; foreach my $key ( keys %toImport ) { %{ $toImport{$key} }= %{ XMLin("./$key.xml") }; } } 1;

            - tye (but my friends call me "Tye")
Re (tilly) 1: Another config file module (any alternative to symbolic refs?)
by tilly (Archbishop) on Oct 30, 2001 at 22:17 UTC
    The answer to the first question is that this is why Perl allows symbolic references. There are other alternatives, but they work out to be worse in this case.

    The answer to the second question is that your module should have a function called import. That will be called as a method when you use the module, and you can use that to let the calling module explain what it wants to ask for, elminating your synchronization problem.

    The random tidbit that I think will be most likely to help is that you should have a search path that is readily configurable, and if at all possible you should set things up so that you can selectively override information in the path, and so that in development you pick up information differently from what you do in production.

    This will make testing, developing, and deploying your system much simpler and more flexible.

Re: Another config file module (any alternative to symbolic refs?)
by doc (Scribe) on Oct 30, 2001 at 22:28 UTC

    Symrefs have their place and on some very *rare* occasions they are useful. Avoiding them when possible makes sense but performing contortions to avoud using them makes little sense. As you already know they are bad you must be qualified to use them ;-)

    Using AUTOLOAD and caller() to autogenerate functions on the fly is another option. You should have a look at AutoLoader +/- AutoSplit for more on dynamic loading.

    doc

Okay, I'll bite:
by perrin (Chancellor) on Oct 30, 2001 at 23:32 UTC
    So, why are you re-inventing the wheel?

    UPDATE: Oh come on! He said "If you're curious about why I am 're-inventing the wheel' in this way, I'll be glad to explain." I'm just taking him up on it.

Re: Another config file module (any alternative to symbolic refs?)
by impossiblerobot (Deacon) on Oct 30, 2001 at 23:56 UTC
    Thanks to all!

    This is exactly what I needed. I got extremely helpful answers to both my questions; perhaps next time I need help I'll be a little less fearful. :-)

    On question one: I'm glad this is one of those rare occasions where symbolic refs seem to be the proper answer. It makes things easier.
    On question two: Obviously I was just using Exporter's import function. I had never considered writing my own -- and I never would have without your help. Thanks.

    As to why I am re-inventing this particular wheel, where would be the best place to post my rambling explanation? Meditations?

    Impossible Robot