The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Config::Merge - Merge configurations from various sources

SYNOPSIS

    use Config::Merge;
    $conf = merge_config([$def_config, $config_file_name, $custom_config]);

    # or you may want different order with external
    # config parser provided in CODE reference
    my $conf = merge_config({
        order => [qw/file default custom/],
        parser => sub {
            require Config::General;
            my %conf = Config::General->new($_[0])->getall;
            return \%conf;
        },
        default => $default_config,
        file => $config_file_name,
        custom => $custom_config,
    });

ABSTRACT

Config::Merge merges configuration from at most three sources. Your application may allow users to define configuration in a file, but you also have set predefined (default) configuration. At the end you want single configuration by merging them with a certain precedence. This module will do just that.

DESCRIPTION

There is a plenty of configuration readers/parsers floating around, Config::Merge is not trying to be another one. It helps you to merge various configuration sources so you get the final configuration structure based on predefined order of precedence.

Config::Merge defines three types of configuration source (in order of precedence from lowest to higest): default, file, and custom.

default

Configuration of type default contains predefined values for parameters. It's meant to be overridden by other source of configuration. Whenever a parameter exists in other source, then the value in the default one will be replaced. You should set your complete parameters in default type.

file

Configuration of type file comes from a file defined by the user of the application. In standard operation, each parameter with defined value will override corresponding parameter in the default type.

custom

Custom configuration comes from other sources than default and file. In standard operation it holds the highest precedence over the others. It's meant to temporarily set certain parameters in certain condition.

How to Merge Configuration

In its standard operation, Config::Merge will take default type as the base configuration to iterate the keys. From there, it will examine other types for existing keys to override the values of the base.

Let's say your application will read configuration from a file,

    my $conf_file = "$HOME/.myappl.conf";

That's the type of file. And you define a set of default configuration,

    my %default_conf = (
        common_printer => '',
        print_command => 'cat > /tmp/dummy-output.txt',
        paper_type => 'A4',
    );

which is a type of default. Since your application is highly customizable, you also allow some command line parameters which you parse in some way,

    my $cmdline_opts = parse_cmdline_options(); # defined somewhere else

so you have the last type, custom. In order to get a single configuration structure, you simply call the merge_config() function and pass in the configuration sources in ARRAY reference. It will return the final form in HASH reference. This function is exported by default. If there's something wrong in the file parsing process, it will simply croak.

    use Config::Merge;
    my $conf = merge_config([\%default, $conf_file, $cmdline_opts]);

Remember that you must pass in your configuration sources in the right order: default, file, and custom. However, you can specify different order by using order option.

Config::Merge provides internal file configuration parser. The reason for this is two folds. First, for convenience reason to avoid dependency on external parser. Second, historically, I've written this routine long long time ago so why I don't just reuse it.

Again, you can specify your favourite parser to suite your need using parser option. This option takes CODE reference as its argement and the coderef will be passed in the filename. The CODE reference is expected to return a HASH reference. False value will be regarded as error.

Now that you use options to change Config::Merge's behaviour, you need to specify your sources via options as well. And you will pass in your options in HASH reference to merge_config.

    my $conf = merge_config({
        order => [qw(default custom file)], # lowest to highest
        parser => \&Config::Auto::parse, # need require() or use()
        custom => $cmdline_opts,
        file => $conf_file,
        default => \%default,
    });

Well, that's all there is to merge your configuration sources. Now I'm about to explain the file format expected by the internal parser.

Internal Parser

The internal parser is very simple and general. The rules are the following.

o

Empty lines are ignored.

o

Lines start with # are comment and ignored as well.

o

Whitespaces are generally insignificant. Leading and trailing whitespaces are removed as well as whitespaces surrounding the equal sign.

o

You may use double quotes ("") in the values to preserve whitespaces.

o

Each line contains a pair of parameter and value separated by equal sign (=). However, multiline for single parameter is supported by adding a backslash (\) at the end of the continuation lines.

o

Multivalue is supported by separating the values with comma (,). Use double quotes ("") to preserve commas in values.

o

Empty value for a parameter will be regarded as empty string, not undefined. If you want the latter simply don't define the parameter at all.

DEPENDENCIES

Text::ParseWords

Internal parser uses Text::ParseWords::parse_line() to parse configuration file. This module is part of standard distribution.

Sub::Usage

It's used to issue insufficient-parameter error from subroutines. Available at CPAN.

Test::More

For testing (with make test) during installation.

CAVEATS

o

lack of testing for external configuration parser, only tested with Config::Auto and Config::General.

FUTURE PLANS

o

accepting multiple files and merge them as well in the order they are defined.

o

make parser option to directly take the package or class name of the external configuration reader/parser.

o

(probably) allow more than three (unlimited?), sources of configuration.

o

allow preparsed configuration (in HASH ref) as value for file type instead of merely filename.

AUTHOR

Hasanuddin Tamir <hasant@cpan.org>

I highly appreciate any feedback, even a single comment, about this module.

COPYRIGHT AND LICENSE

Copyright 2003 by Hasanuddin Tamir. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

Various configuration parsers from CPAN.