OK, I did it. Rather than my usual rant, lets post some bona-fide code. This is really rough, a lot of it is cut and paste from my other stuff, but at this point it's working. It may not work for you, as I've diked out a lot of the really ugly stuff before pressing submit ;-) Consider this untested.
package Config;
use strict; # always be strict
use Carp;
use vars qw ($AUTOLOAD);
my ($config); # our global config object
my (%config); # config hash, the actual config
+data
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
# setup the new object
my $self = {
%config,
};
bless ($self, $class);
return ($self);
}
sub AUTOLOAD {
my $self = $config;
my $type = ref($self);
my $name = $AUTOLOAD;
$name =~ s/.*://; # strip fully-qualified portion
unless ( defined $self->{$name} ) {
croak "Can't access `$name' field in class $type";
}
# just return the attribute
return $self->{$name};
}
sub read_config {
my $conf_file = shift;
open (FILE, "$conf_file") || return 0;
while (<FILE>) {
if ( /^(\w+)\s*=?\s*(.*)$/ ) {
$config->{$1} = $2;
carp "w00t! set $1 to $2";
}
}
close (FILE);
return 1;
}
# package constructor
BEGIN {
my (@config_files);
$config = Config->new;
# we have an empty configuration object, lets read in
# a config file
# if we fail, fail silently, give the user code a chance to call rea
+d_config
# with it's own specifier
@config_files = qw ( ../etc/journal.conf /usr/local/etc/journal.conf
+ );
# try each one until we succeed
foreach (@config_files) {
if (read_config ($_)) {
last;
}
}
# error check
if (! $config ) {
carp "Failed to get config";
}
}
# keep stuff happy
1;
With a config file like this:
rootdir = /usr/tmp
My code can do this:
use Config;
print "Root Directory is " . Config->rootdir . "\n";
All of my modules can
use config;, the config data will only be read once.
The other bit of my criteria, allowing for a user override of the config file I haven't yet nutted out. I have a feeling it's going to cause me problems, given that some of my modules need config data during their class constructers. I'll keep on that.