In the recent best practices document that Mark started, he mentions
configuration information that is global, i.e. is needed by more than
one cgi script. What CPAN configuration modules are people using in
their CGI::Apps?
Hi,

I am not using any CPAN module, but wrote a small module myself.
You can see it below (comments appreciated).

Features:

- configuration files usually are just Perl files, returning a hashref

example:
{ tmpl_path => '/path/to/templates',
log_level => 3,
}

using Perl files gives maximum flexibility,
with security problems pointed out elsewhere.
(I am thinking of using the Safe module to check these)

- configuration files can be in other formats by providing an
input processor, which is just a coderef
(see method get_raw below for an example)

- the data read from the files is cached, but reloaded if the file is changed
(with a 5 second delay to minimize stat() calls)
this makes it very efficient in mod_perl


Synopsis:

my $config = My::Configuration->get('/path/to/config.pl');

$config is a hashref with parameters.


Cheers,

Thilo


====== CODE BELOW =======

package My::Configuration;
use strict;
use FileHandle;

# global config file cache
my %CACHE = ();

# modification times of the data in the caches
my %MOD_TIMES = ();


# get the raw contents of a file
# as an array(ref) of lines
sub get_raw{
my ($class, $filename) = @_;
return My::Configuration->get($filename,
sub{
my $fh = shift;
my @result = <$fh>;
$fh->close;
return \@result;
}
);
}


# get the contents of a configuration file
#
# the file will be 'done', unless an optional
# processor subref is specified, in which case
# the processor gets to read the file
# and return a reference to something

sub get{
my ($class, $filename, $processor) = @_;

unless (defined $filename){
warn "cannot load configuration without a filename!";
return;
}
my $ref;
# try to use the cached version
my $cache_age = $MOD_TIMES{$filename};
if ($cache_age and time - $cache_age < 6){
# check only every five seconds
return $CACHE{$filename};
}

my $mod = (stat($filename))[9];
# file exists
if ($mod){
if ($cache_age and $mod == $cache_age){
# cached data has not changed
return $CACHE{$filename};
}
}
else{
warn "missing configuration file $filename \n";
}

$ref = ref $processor eq 'CODE' ?
$processor->(new FileHandle $filename, 'r') :
do $filename;

unless (ref $ref){
$ref = defined $ref ? "'$ref'" : '<undef>';
my $message="broken configuration file $filename:\n";
$message .= "parse error: $@\n" if $@;
$message .= "load error: $!\n" if $!;
$message .= "returned not a ref, but $ref\n" unless $@ || $!;
# die if no previous configuration
exists $CACHE{$filename} ?
warn ($message) : die ($message);
return $CACHE{$filename};
}
$CACHE{$filename} = $ref;
$MOD_TIMES{$filename} = $mod;
return $ref;
}


---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to