in reply to Application-wide configuration

I found it interesting to add a Singleton wrapper around an existing Configuration reading object - so that I could gain easy access to configuration settings from my CGI applications.

=head1 NAME Singleton::Config - A singleton wrapper around our site's configuratio +n file. =head1 SYNOPSIS =for example begin #!/usr/bin/perl -w use Singleton::Config; use strict; # Get object. my $db = Singleton::Config->instance(); # Read database details my $db_user = $db->get( "database", "username" ); my $db_pass = $db->get( "database", "password" ); =for example end =head1 DESCRIPTION This object is a Singleton wrapper around the global configuration file used for our site. =cut package Singleton::Config; use strict; use warnings; use Config::General; # # The single, global, instance of this object # my $_config; =head2 instance Gain access to the configuration file instance. =cut sub instance { $_config ||= (shift)->new(); } =head2 new Constructor. =cut sub new { my ( $proto, %supplied ) = (@_); my $class = ref($proto) || $proto; my $self = {}; $self->{'loaded'} = 0; bless ($self, $class); return $self; } =head2 get Read a configuration file either from the named block + paam, or the single param. =cut sub get { my($self, $block , $param ) = (@_ ); # load the file if we've not already done so. $self->_load() if ( !$self->{'loaded'} ); my $result; if ( defined( $param ) ) { $result = $self->{'data'}{$block}->{$param}; } else { $result = $self->{'data'}{$block} ; } return( $result ); } =head2 _load Load the data from the on-disk file. =cut sub _load { my ( $self ) = ( @_ ); my $file = undef; my @opts = ( "../conf/site.conf", "conf/site.conf" ); foreach my $attempt ( @opts ) { if ( -e $attempt && !defined( $file ) ) { $file = $attempt; } } die "No configuration file " unless ( defined( $file ) && ( -e $fi +le ) ); # # Load the data. # my $conf = new Config::General( -ConfigFile => $file, -LowerCaseNames => 1 ); my %data = $conf->getall; # # Save it. # $self->{'data'} = \%data; $self->{'loaded'} = 1; } 1; =head1 AUTHOR Steve Kemp http://www.steve.org.uk/ =cut
Steve
--

Replies are listed 'Best First'.
Re^2: Application-wide configuration
by akho (Hermit) on Jul 27, 2007 at 20:06 UTC
    Yeah, that looks much like what I'm doing.

    Why do you need the get method? Shouldn't that be accessible through the instance?

    You can also put it the other way round: why do you need instances if you can get things with a class method?

    I may misunderstand something.

    Discussion on subclassing and its uses (above) may also apply if your usage patterns are similar to mine; that's a matter of taste, though. (You'll need to use a fully qualified name for $_config in this module if you do subclass).

      In the code above you need the get method because the singleton returns an instance of itself, not of the configuration object.

      So usage becomes:

      my $config = Singleton::Config->instance(); my $random = $config->get( "block", "setting" );
      Steve
      --