Config Loader

Recent site activity

Use cases

  1. The "basic" C::P::ConfigLoader scenario

    User has main config "myapp.conf", and wants to allow local overrides in "myapp_local.conf"
  2. Directory tree

    User has a number of files in a directory tree. CL recurses through the tree, loading each file, and inserting it into the config hash with the directory name and the file name as branches in the tree, for instance:

    /app
        /db
           /main.conf

    ->

    $config = { app => { db => { main => $file_contents }}}


     The contents of local override files could be applied at any point in the tree.
  3. Specific filename

    # Load the config directly
    my $config = Config::Loader->new( file => path/to/config.conf )


    path/to/application_home/xyzzy.conf
    path/to/application_home/xyzzy_local.conf
    path/to/application_home/xyzzy.yml
    path/to/application_home/xyzzy_local.yml
    ...
  4. Base file name

    # Guess at possible config files
    my $config = Config::Loader->new( name => xyzzy, path => path/to/application_home/ )
  5. Using ENV for file location

    With the second style of instantiation, Config::JFDI will also lookup $ENV{uc $name . _CONFIG}, etc. for ENV overriding
  6. Filtering which files are loaded

    Only load that config files that (eg) pertain to this process' role, or are relevant to this particular machine (eg with hostname).

    $config = Config::Loader->new({
        path            => '/path/to/load',       
        load_if         => qr/.*_daemon/,
      | skip_if         => qr/.*_daemon/,
    });

    load_if and skip_if could accept scalars (eq), regexes, code refs, hash refs (exists), or array refs containing any of the previous (load_if loads and skip_if skips at the first true value).

    The matching would be performed against the 'pseudo-path', for instance for './app/db/main.yaml', the matching would be performed against 'app.db.main'. 

    Should
    skip_if be called load_unless instead, for concistency with merge_if / merge_unless below?

  7. Filtering which files are merged (local overrides)

    The user may want to control which files are intended for merging, instead of loading:

    $config = Config::Loader->new({
        path            => '/path/to/load',       
        merge_if        => qr/.*_local/,
      | merge_unless    => qr/.*_local/,
    });   
    To be considered for merging, the file would first have to be have passed the load_if and skip_if checks.
  8. Now for something different

Config::Loader::Plugin::
Config::Loader::Stack # Each read configuration gets pushed onto this
Config::Loader::Read::
Config::Loader::Read::Any (... using Config::Any)
Config::Loader::Read::General (... using Config::General)

my $loader = Config::Loader->new
$loader->setup_reader('Any' => { ... Any setup (name, _local suffix, look at $ENV, etc)... })
$loader->setup_reader('General')
$loader->setup_parser('Substitute') # Does C::P::ConfigLoader style substituting

$loader->read({ ... A hash containing default values ... })
$loader->read( 'any:path/to/config/directory' )
$loader->read( 'path/to/general-style.cnf' )
$loader->read( 'general:unknown-extension.txt' )

my $config = $loader->load # Does parsing and merging


Now the idea above is that Config::Loader just provides an API for people to use. We should provide Config::Loader::Simple for 90% of the people that don't care how it's done, they just what something loaded from disk.

The advantage of the above approach is that people can easily cobble together their own config loader in MyApplication::Config namespace using the Config::Loader API

The above 1-7 ideas can be subsumed as custom readers/parser/mergers or plugins overloading the read/parse/merge phase.


Comments (1)

Tomohiro Teranishi - Aug 24, 2008 2:15 AM

Hi!! Config::Loader looks really nice!!

below is my castalyst-config-use-case article, i just want to show how I implement Config Class in Catalyst App. hehe thanks.

http://tomyhero.vox.com/library/post/catalyst-config.html