@list = C('my.path.to.a.list');
$ref = C('my.path.to.whatever');
$array_el = C('my.path.to.array.element.3');
####
$host = $c->get_dbconfig->{servers}[2]{host};
as opposed to:
$host = C('dbconfig.servers.2.host');
####
global.conf:
username : admin
password : 12345
####
$Config = {
global => {
username => 'admin',
password => '12345',
}
}
####
confdir:
syndication/
--data_types/
--traffic.conf
--headlines.conf
--data_types.conf
syndication.conf
####
confdir:
db.conf
local.conf
####
connections:
default_settings:
host: localhost
table: abc
password: 123
####
db:
connections:
default_settings:
password: 456
####
db:
connections:
default_settings:
host: localhost
table: abc
password: 456
####
file: MyApp/Config.pm:
----------------------
package MyApp::Config;
use base 'Burro::Config';
file: (eg) startup.pl:
----------------------
## package main;
# this loads the configuration data from the provided directory
# the dir is only ever specified once
use MyApp::Config '/path/to/config/dir';
file: MyApp/Other/Module.pm
---------------------------
package MyApp::Other::Module;
# this imports the sub C() into the current package to give access
# to the configuration data
use MyApp::Config;
@dbs = C('db.server_pool");
####
package MyApp::Config;
our @ISA=('Burro::Config');
use Burro::Config();
package main;
use lib ('/path/to/Burro');
MyApp::Config->import('/opt/apache/sites/iAnnounce/config');
# normally wouldn't want C() to be exported package main
# but for testing purposes
MyApp::Config->import();
print C('my.config.value');
####
package Burro::Config;
use strict;
use warnings FATAL => 'all', NONFATAL => 'redefine';
use File::Glob qw(:glob);
use YAML::Syck();
BEGIN {
$YAML::Syck::ImplicitUnicode = 1;
}
use Storable();
use Data::Alias qw(deref);
=head1 NAME
Burro::Config - access configuration data across your application
=head1 SYNOPSIS
-------------------------
file: MyApp/Config.pm:
package MyApp::Config;
use base 'Burro::Config';
file: (eg) startup.pl:
# package main;
use MyApp::Config '/path/to/config/dir';
file: MyApp/Other/Module.pm;
package MyApp::Other::Module;
use MyApp::Config;
@dbs = C('db.server_pool");
-------------------------
$dbs = MyApp::Config::copy_C('db.server_pool');
($value,$label) = MyApp::Config->value_label('uk "United Kingdom");
=head1 DESCRIPTION
Burro::Config is a configuration module which has five aims:
=over
=item *
Store all configuration in an easy to read (see L) format with
a flexible structured layout. See L"Config file layout">
=item *
Provide a simple, easy to read, concise way of accessing the configuration values.
See L"Using config in applications">
=item *
Specify the location of the configuration files only once per
application, so that it requires minimal effort to relocate.
See L"Implementing Burro::Config">
=item *
Allow different applications (eg web sites in mod_perl) each to have their own configuration
data, without having to pass an object around.
=item *
Provide a way for overriding configuration values on a particular
machine, so that differences between (eg) the dev environment and
the live environment do not get copied over accidentally.
See L"Overriding config locally">
=item *
Load all config at startup so that (eg in the mod_perl environment) the
data is shared between all child processes. See L"Using config in applications">
=back
=head2 Implementing Burro::Config
Burro::Config is never used directly by applications. It should always
be subclassed. The configuration data gets stored in the subclassing module.
package MyApp::Config;
use base 'Burro::Config';
package MyApp::Other::Module;
use MyApp::Config;
Only C uses C directly. All the other
modules which require access to the config data use C.
B Whenever either C or C are
'use'd, they should not be followed by empty parentheses. Their
functionality relies on C being called. So:
use Burro::Config;
NOT
use Burro::Config();
=head2 Config file layout
Burro::Config uses L for its configuration files.
Configuration files can be stored in their own directory tree
or mixed up with other files (but why would you do this?). When
loading your config data, Burro::Config starts at the directory
specified at startup (see L"Using config in applications">) and looks
for any file ending in C<.conf> and at any subdirectories.
The name of the file or subdirectory is used as the first key. So:
global.conf:
username : admin
password : 12345
would be stored as :
$Config = {
global => {
username => 'admin',
password => '12345',
}
}
Subdirectories are processed before the current directory, so
you can have a directory and a config file with the same name,
and the values will be merged into a single hash, so for
instance, you can have:
confdir:
syndication/
--data_types/
--traffic.conf
--headlines.conf
--data_types.conf
syndication.conf
The config items in syndication.conf will be added to (or overwrite)
the items loaded into the syndication namespace via the subdirectory
called syndication.
=head2 Overriding config locally
The situation often arises where it is necessary to specify
different config values on different machines. For instance,
the database host on a dev machine may be different from the host
on the live application.
Instead of changing this data during dev and then having to remember
to change it back before putting the new code live, we have a mechanism
for overriding config locally in a C file and then, as long as
that file never gets uploaded to live, you are protected.
You can put a file called C in any sub-directory, and
the data in this file will be merged with the existing data.
For instance, if we have:
confdir:
db.conf
local.conf
and db.conf has :
connections:
default_settings:
host: localhost
table: abc
password: 123
And in local.conf:
db:
connections:
default_settings:
password: 456
the resulting configuration will look like this:
db:
connections:
default_settings:
host: localhost
table: abc
password: 456
=head2 Using config in applications
=over
=item Specifying the config directory
The config directory can only be specified once, the very first time
that C is 'use'd. For instance:
use MyApp::Config '/opt/myapp/config';
This statement causes the config files in that directory and sub-directories
to be loaded.
Every other module which needs access to the config, just needs:
use MyApp::Config; # NOTE : no parenthese ()
=item Refering to config
Whenever C