Hi all,

a long time ago in a previous job I wrote a module for building configuration information. It was never published. I'm about to recreate it but first I want to make sure I'm not reinventing the wheel and I'm also looking for suggestions/comments.

First off, this is not a module for reading configuration info, there are plenty of them. This module (let's call it Config::Builder) would handle what comes after you have read in the config file.

Usually after you've read various config files you have to stitch pieces together into paths, urls and other things. This can be done with perl but it can be a bit tedious and is probably better done in a declarative fashion.

Here's an example of how the module will work (the old module was much the same except it required lots of [] and "")

my $factory = Config::Builder->new qw( user => user admin => admin htmldir => %path $basedir html userdir => %path $htmldir $user admindir => %path $htmldir $admin email => %join $username @ $domain ); my $values = read_your_config_file(); # returns a hash of values my $config = $factory->make_config($values); print "user dir is ".$config->("userdir")."\n"; print "admin dir is ".$config->("userdir")."\n";

a bare word is interpretted as a string, a $ indicates the value should come from the config hash (possibly requiring further calculations to get that value), %something indicates that the values after will processed in a particular way, so for example %path means the following values should be joined together with path separators.

What this prints depends on the hash entries in $values so for example

$values = { basedir => "/base/dir" } /base/dir/html/user /base/dir/html/admin ----
$values = { basedir => "/base/dir", user => "customuser", } /base/dir/html/customuser /base/dir/html/admin ---
$values = { basedir => "/base/dir", htmldir => "/custom/html/dir", } /custom/html/dir/user /custom/html/dir/admin

Basically, anything that is not specified in $values is constructed according to the rules but you can override any rule by specify a value for it.

Without this module you'd have to do

my $c = read_your_config_file(); # returns a hash of values use File::Spec::Functions; $c->{user} ||= "user"; $c->{admin} || = "admin"; $c->{htmldir} ||= catfile($c->{basedir}, $c->{html}); $c->{userdir} ||= catfile($c->{htmldir}, $c->{user}); $c->{admindir} ||= catfile($c->{htmldir}, $c->{admin}); $c->{email} ||= "$c->{username}\@$c->{domain}";

which has several disadvantages: it's

Finally, with Config::Builder it'll be possible to combine rule sets, inherit from other rule sets and define your own % operators.

Any comments on the interface or pointers to already existing modules appreciated. Otherwise I'm going to start typing.

Updated: changed title to RFC.

Updated: 26/11/2004 no suggestions or objections and quite a few votes so I guess it's good as it is. I'm nearly finished this but I've got to go away for 6 weeks but I'll finish it when I come back.