Provided by: libconfig-merge-perl_1.04-3_all bug

NAME

       Config::Merge - load a configuration directory tree containing YAML, JSON, XML, Perl, INI or
       Config::General files

SYNOPSIS

          OO style
          -------------------------------------------------------
          use Config::Merge();

          my $config    = Config::Merge->new('/path/to/config');

          @hosts        = $config->('db.hosts.session');
          $hosts_ref    = $config->('db.hosts.session');
          @cloned_hosts = $config->clone('db.hosts.session');
          -------------------------------------------------------

       OR

          Functional style
          -------------------------------------------------------
          # On startup
          use Config::Merge('My::Config' => '/path/to/config');

          # Then, in any module where you want to use the config
          package My::Module;
          use My::Config;

          @hosts        = C('db.hosts.sesssion');
          $hosts_ref    = C('db.hosts.sesssion');
          @cloned_hosts = My::Config::clone('db.hosts.session');
          $config       = My::Config::object;
          -------------------------------------------------------

       ADVANCED USAGE

          OO style
          -------------------------------------------------------
          my $config    = Config::Merge->new(
              path      => '/path/to/config',
              skip      => sub {} | regex | {} ,
              is_local  => sub {} | regex | {} ,
              load_as   => sub {} | regex ,
              sort      => sub {} ,
              debug     => 1 | 0
          );
          -------------------------------------------------------

          Functional style
          -------------------------------------------------------
          use Config::Merge(
              'My::Config' => '/path/to/config',
              {
                  skip      => sub {} | regex | {} ,
                  is_local  => sub {} | regex | {} ,
                  load_as   => sub {} | regex ,
                  sort      => sub {} ,
                  debug     => 1 | 0
              }
          );

          # Also, you can subclass these:

            package My::Config;
            sub skip {
                ...
            }

          -------------------------------------------------------

DESCRIPTION

       Config::Merge is a configuration module which has six goals:

       •   Flexible storage

           Store  all  configuration  in your format(s) of choice (YAML, JSON, INI, XML, Perl, Config::General /
           Apache-style config) broken down into individual files in a configuration directory  tree,  for  easy
           maintenance.
            See "CONFIG TREE LAYOUT"

       •   Flexible access

           Provide  a  simple,  easy  to  read,  concise  way  of accessing the configuration values (similar to
           Template). See "ACCESSING CONFIG DATA"

       •   Minimal maintenance

           Specify the location of the configuration files only  once  per  application,  so  that  it  requires
           minimal effort to relocate.  See "USING Config::Merge"

       •   Easy to alter development environment

           Provide  a  way  for  overriding  configuration  values on a development machine, so that differences
           between the dev environment and the live environment  do  not  get  copied  over  accidentally.   See
           "OVERRIDING CONFIG LOCALLY"

       •   Minimise memory use

           Load  all  config  at startup so that (eg in the mod_perl environment) the data is shared between all
           child processes. See "MINIMISING MEMORY USE"

       •   Flexible implementation

           You may want to use a different schema for your configuration files, so you can pass in (or subclass)
           methods for determining how your files are merged.  See "ADVANCED USAGE".

USING "Config::Merge"

       There are two ways to use "Config::Merge":

       OO STYLE
              use Config::Merge();
              my $config    = Config::Merge->new('/path/to/config');

              @hosts        = $config->('db.hosts.session');
              $hosts_ref    = $config->('db.hosts.session');
              @cloned_hosts = $config->clone('db.hosts.session');

           Also, see "ADVANCED USAGE".

       YOUR OWN CONFIG CLASS (functional style)
           The following code:

              # On startup
              use Config::Merge('My::Config' => '/path/to/config');

           •   auto-generates the class "My::Config"

           •   loads the configuration data in '/path/to/config'

           •   creates the subs "My::Config::C", "My::Config::clone" and "My::Config::object".

           Then when you want your application to have access to your configuration data, you add  this  (eg  in
           your class "My::Module"):

              package My::Module;
              use My::Config;       # Note, no ()

           This exports the sub "C" into your current package, which allows you to access your configuation data
           as follows:

              @hosts        = C('db.hosts.sesssion');
              $hosts_ref    = C('db.hosts.sesssion');
              @cloned_hosts = My::Config::clone('db.hosts.session');
              $config       = My::Config::object;

CONFIG TREE LAYOUT

       Config::Merge  reads the data from any number (and type) of config files stored in a directory tree. File
       names and directory names are used as keys in the configuration hash.

       It uses file extensions to decide what type of data the file contains, so:

           YAML            : .yaml .yml
           JSON            : .json .jsn
           XML             : .xml
           INI             : .ini
           Perl            : .perl .pl
           Config::General : .conf .cnf

       When loading your config data, Config::Merge starts at the directory specified  at  startup  (see  "USING
       Config::Merge")  and  looks  through  all  the  sub-directories  for  files  ending  in  one of the above
       extensions.

       The name of the file or subdirectory is used as the first key.  So:

           global/
               db.yaml:
                   username : admin
                   hosts:
                            - host1
                            - host2
                   password:
                     host1:   password1
                     host2:   password2

       would be loaded as :

           $Config = {
              global => {
                  db => {
                      username => 'admin',
                      password => { host1 => 'password1', host2 => 'password2'},
                      hosts    => ['host1','host2'],
                  }
              }
           }

       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.yaml
                --headlines.yaml
              --data_types.ini
              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.

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. Also, see "ADVANCED USAGE" which provides you with other means to merge local data.

       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 "local.*" file and then, as long as
       that file never gets uploaded to live, you are protected.

       You can put a file called "local.*" (where * is any of the recognised extensions) in  any  sub-directory,
       and the data in this file will be merged with the existing data.

       Just make sure that the "local.*" files are never checked into your live code.

       For instance, if we have:

           confdir:
               db.yaml
               local.yaml

       and db.yaml has :

           connections:
               default_settings:
                   host:       localhost
                   table:      abc
                   password:   123

       And in local.yaml:

           db:
               connections:
                   default_settings:
                       password:   456

       the resulting configuration will look like this:

           db:
               connections:
                   default_settings:
                       host:       localhost
                       table:      abc
                       password:   456

ACCESSING CONFIG DATA

       All configuration data is loaded into a single hash, eg:

           $config = {
               db    => {
                   hosts  => {
                       session  => ['host1','host2','host3'],
                       images   => ['host1','host2','host3'],
                       etc...
                   }
               }
           }

       If you want to access it via standard Perl dereferences, you can just ask for the hash:

           OO:
              $data_ref  = $config->();
              $hosts_ref = $data_ref->{db}{hosts}{session};
              $host_1    = $data_ref->{db}{hosts}{session}[0];

           Functional:
              $data_ref  = C();
              $hosts_ref = $data_ref->{db}{hosts}{session};
              $host_1    = $data_ref->{db}{hosts}{session}[0];

       However,  "Config::Merge"  also  provides  an easy to read dot-notation in the style of Template Toolkit:
       "('key1.key2.keyn')".

       A key can be the key of a hash or the index of an array. The return value is  context  sensitive,  so  if
       called in list context, a hash ref or array ref will be dereferenced.

           OO:
              @hosts     = $config->('db.hosts.session');
              $hosts_ref = $config->('db.hosts.session');
              $host_1    = $config->('db.hosts.session.0');

           Functional:
              @hosts     = C('db.hosts.session');
              $hosts_ref = C('db.hosts.session');
              $host_1    = C('db.hosts.session.0');

       These lookups are memo'ised, so lookups are fast.

       If the specified key is not found, then an error is thrown.

MINIMISING MEMORY USE

       The  more configuration data you load, the more memory you use. In order to keep the memory use as low as
       possible for mod_perl (or other forking applications), the configuration data should be loaded at startup
       in the parent process.

       As long as the data is never changed by the children, the configuration hash will  be  stored  in  shared
       memory, rather than there being a separate copy in each child process.

       (See <http://search.cpan.org/~pgollucci/mod_perl-2.0.3/docs/user/performance/mpm.pod>)

METHODS

       "new()"
               $conf = Config::Merge->new($config_dir);

           new()  instantiates  a  config object, loads the config from the directory specified, and returns the
           object.

       "C()"
             $val = $config->C('key1.key2.keyn');
             $val = $config->C('key1.key2.keyn',$hash_ref);

           "Config::Merge" objects are overloaded so that this also works:

             $val = $config->('key1.key2.keyn');
             $val = $config->('key1.key2.keyn',$hash_ref);

           Or, if used in the functional style (see "USING Config::Merge"):

             $val = C('key1.key2.keyn');
             $val = C('key1.key2.keyn',$hash_ref);

           "key1" etc can be keys in a hash, or indexes of an array.

           "C('key1.key2.keyn')" returns everything from "keyn" down, so you can use the return  value  just  as
           you would any normal Perl variable.

           The  return values are context-sensitive, so if called in list context, an array ref or hash ref will
           be returned as lists.  Scalar values, code refs, regexes and blessed objects will always be  returned
           as themselves.

           So for example:

             $password = C('database.main.password');
             $regex    = C('database.main.password_regex');

             @countries = C('lists.countries');
             $countries_array_ref = C('lists.countries');

             etc

           If  called  with a hash ref as the second parameter, then that hash ref will be examined, rather than
           the $config data.

       "clone()"
           This works exactly the same way as "C()" but it performs a deep clone of the  data  before  returning
           it.

           This  means  that  the  returned  data  can be changed without affecting the data stored in the $conf
           object;

           The data is deep cloned, using Storable, so the bigger the data,  the  more  performance  hit.   That
           said, Storable's dclone is very fast.

       "register_loader()"
               Config::Merge->register_loader( 'Config::Merge::XYZ');

               Config::Merge->register_loader( 'Config::Merge::XYZ' => 'xyz','xxx');

           By  default, "Config::Merge" uses the "Config::Any" plugins to support YAML, JSON, INI, XML, Perl and
           Config::General configuration files, using the standard file extensions to recognise the  file  type.
           (See "CONFIG TREE LAYOUT").

           If you would like to change the handler for an extension (eg, you want ".conf" and ".cnf" files to be
           treated as YAML), do the following:

               Config::Merge->register_loader ('Config::Any::YAML' => 'conf', 'cnf');

           If you would like to add a new config style, then your module should have two methods: "extensions()"
           (which  returns a list of the extensions it handles), and "load()" which accepts the name of the file
           to load, and returns a hash ref containing the data in the file. See Config::Any for details.

           Alternatively, you can specify the extensions when you load it:

               Config::Merge->register_loader ('My::Merge' => 'conf', 'cnf');

       "load_config()"
               $config->load_config();

           Will reload the config files located in the directory specified at object creation (see "new()").

           BEWARE : If you are using this in a mod_perl environment, you will lose the benefit of shared  memory
           by calling this in a child process
            - each child will have its own copy of the data.  See "MINIMISING MEMORY USE".

           Returns the config hash ref.

       "clear_cache()"
               $config->clear_cache();

           Config  data is generally not supposed to be changed at runtime. However, if you do make changes, you
           may get inconsistent results, because lookups are cached.

           For instance:

               print $config->C('db.hosts.session');  # Caches this lookup
               > "host1 host2 host3"

               $data = $config->C('db.hosts');
               $data->{session} = 123;

               print $config->C('db.hosts.session'); # uses cached value
               > "host1 host2 host3"

               $config->clear_cache();
               print $config->C('db.hosts.session'); # uses actual value
               > "123"

       "import()"
           "import()" will normally be called automatically when you "use Config::Merge". However, you may  want
           to do this:

               use Config::Merge();
               Config::Merge->register_loader('My::Plugin' => 'ext');
               Config::Merge->import('My::Config' => '/path/to/config/dir');

           If  called with two params: $config_class and $config_dir, it generates the new class (which inherits
           from Config::Merge) specified in $config_class, creates a new object of  that  class  and  creates  4
           subs:

           "C()"
                   As a function:
                       C('keys...')

                   is the equivalent of:
                       $config->C('keys...');

           "clone()"
                   As a function:
                       clone('keys...')

                   is the equivalent of:
                       $config->clone('keys...');

           "object()"
                   $config = My::Config->object();

               Returns the $config object,

           "import()"
               When you use your generated config class, it exports the "C()" sub into your package:

                   use My::Config;
                   $hosts = C('db.hosts.session');

ADVANCED USAGE

       The  items  in  the section allow you to customise how Config::Merge loads your data.  You may never need
       them.

       You can:

       •   Override array values

       •   Skip the loading of parts of your config tree

       •   Specify which files / dirs are local

       •   Specify how to translate a file / dir name into a key

       •   Change order in which files are loaded

       •   See debug output

       Overriding array values
           Overriding hash values is easy, however arrays are more complex.  it may be simpler to copy and paste
           and edit the array you want to change locally.

           However, if your array is too long, and you want  to  make  small  changes,  then  you  can  use  the
           following:

           In the main config:

               {
                 cron => [qw( job1 job2 job3 job4)]
               }

           In the local file

               {
                 cron => {
                   '3'  => 'newjob4',      # changes 'job4' -> 'newjob4'

                   '!'  => {               # signals an array override

                        '-' => [1],        # deletes 'job2'

                        '+' => ['job5'],   # appends 'job5'

                     OR '+' => {           # inserts 'job3a' after 'job3'
                            2 => 'job3a'
                        }
                   }
               }

           •   The override has to be a hash, with at least this structure
                "{ '!' => {} }" to signal an array override

           •   Any  other  keys  with  integers  are treated as indexes and are used to change the value at that
               index in the original array

           •   The '-' key should contain an array ref, with the indexes of the  elements  to  remove  from  the
               array.

           •   If the '+' key contains an array ref, then its contents are appended to the original array.

           •   If  the  '+'  key contains a hash ref, then each value is inserted into the original array at the
               index given in the key

           •   Indexes are zero based, just as in Perl.

       "skip()"
               $c = Config::Merge->new(
                       path  => '/path/to/config',
                       skip  => qr/regex/,
                                | [ qr/regex1/, qr/regex2/...]
                                | {  name1 => 1, name2 => 2}
                                | sub {}
               );

           "skip()" allows you to skip the loading of parts of your config tree.  For  instance,  if  you  don't
           need a list of cron jobs when running your web server, you can skip it.

           The  decision  is  made  based on the path to that value, eg 'app.db.hosts' rather than on filenames.
           Also, the check is only performed for each new directory or filename -  it  doesn't  check  the  data
           within each file.

           To use "skip()", you can either subclass it, or pass in a parameter to new:

           "qr/regex/" or "[qr/regex1/, qr/regex2]"
               Each  regex will be checked against the key path, and if it matches then the loading of that tree
               will be skipped

           "{key_path => 1}"
               If the key path exists in the hash, then loading will be skipped

           "sub {}" or subclassed "skip"
                  sub {
                      my ($self,$key_path) = @_;
                      ...make decision...
                      return 1 | 0;
                  }

       "is_local()"
               $c = Config::Merge->new(
                       path     => '/path/to/config',
                       is_local => qr/regex/,
                                   | [ qr/regex1/, qr/regex2/...]
                                   | {  name1 => 1, name2 => 2}
                                   | sub {}
               );

           "is_local()" indicates whether a file or dir should be considered part of the main config  (and  thus
           loaded normally) or part of the local config (and thus merged into the main config).

           The decision is made based on the name of the file / dir, without any extension.

           To use "is_local()", you can either subclass it, or pass in a parameter to new:

           "qr/regex/" or "[qr/regex1/, qr/regex2]"
               Each  regex  will  be checked against the file/dir name, and if it matches then that tree will be
               merged

           "{filename => 1, dirname => 1}"
               If the file/dir name exists in the hash, then that tree will be merged

           "sub {}" or subclassed "is_local"
                  sub {
                      my ($self,$name) = @_;
                      ...make decision...
                      return 1 | 0;
                  }

           See "EXAMPLE USING is_local() AND load_as()".

       "load_as()"
               $c = Config::Merge->new(
                       path     => '/path/to/config',
                       load_as  => qr/(regex)/,
                                   | sub {}
               );

           "load_as()" returns the name of the key to use when loading the file / dir. By  default,  it  returns
           the $name for main config files, or '' for local files.

           The decision is made based on the name of the file / dir, without any extension.

           If  "load_as()" returns an empty string, then each key in the file/tree is merged separately. This is
           how the "local.*" files work by default.  See "OVERRIDING CONFIG LOCALLY".

           For instance:

              main.yaml:
                key1:  value
                key2:  value

              db.yaml:
                key3:  value
                key4:  value

              local.yaml:
                main:
                   key1: new_value
                db:
                   key4: new_value

           To use "load_as()", you can either subclass it, or pass in a parameter to new:

           "qr/(regex)/"
               The regex will be checked against the file/dir name, and if it matches then it returns the string
               captured in the regex, otherwise it returns the original name.

           "sub {}" or subclassed "is_local"
                  sub {
                      my ($self,$name,$is_local) = @_;
                      ...make decision...
                      return 'string';   # string is used as the keyname
                      return '';         # acts like local.* (see above)
                      return undef;      # don't load this file/dir
                  }

           Also, see "EXAMPLE USING is_local() AND load_as()".

       EXAMPLE USING "is_local()" AND "load_as()"
           For instance, instead of using "local.*" files, you may  want  to  keep  versioned  copies  of  local
           configs for different machines, and so use:

              app.yaml
              app-(dev1.domain.com).yaml
              app-(dev2.domain.com).yaml

           You would implement this as follows:

               my $config = Config::Merge->new(
                   path        => '/path/to/config',

                   # If matches 'xxx-(yyy)'
                   is_local    => sub {
                       my ( $self, $name ) = @_;
                       return $name=~/- [(] .+ [)]/x ? 1 : 0;
                   },

                   # If local and matches 'xxx-(hostname)', return xxx
                   load_as => sub {
                       my ( $self, $name, $is_local ) = @_;
                       if ($is_local) {
                           if ( $name=~/(.*) - [(] ($hostname) [)] /x ) {
                               return  $1;
                           }
                           return undef;
                       }
                       return $name;
                   }
               );

           See "examples/advanced.pl" for a working illustration.

       "sort()"
               $c = Config::Merge->new(
                       path   => '/path/to/config',
                       sort   => sub {}
               );

           By default, directory entries are sorted alphabetically, with directories before filenames.

           This would be the order for these directory entries:

             api/
             api-(dev1)/
             api.yaml
             api-(dev1).yaml

           To override this, you can subclass "sort()" or pass it in as a parameter to new:

              sub {
                  my ($self,$names_array_ref) = @_
                  ...sort...
                  return $names_array_ref;
              }

       "debug()"
               my $config = Config::Merge->new(
                   path        => '/path/to/config',
                   debug       => 1 | 0
               );

           If "debug" is true, then Config::Merge prints out an explanation of what it is doing on STDERR.

SEE ALSO

       Storable,   Config::Any,   Config::Any::YAML,   Config::Any::JSON,   Config::Any::INI,  Config::Any::XML,
       Config::Any::General

THANKS

       Thanks to Hasanuddin Tamir [HASANT] for vacating the Config::Merge namespace, which allowed me to  rename
       Config::Loader to the more meaningful Config::Merge.

       His          version          of          Config::Merge          can          be         found         in
       <http://backpan.cpan.org/modules/by-authors/id/H/HA/HASANT/>.

       Thanks to Joel Bernstein and Brian Cassidy for the interface to the various configuration  modules.  Also
       to Ewan Edwards for his suggestions about how to make Config::Merge more flexible.

BUGS

       No bugs have been reported.

       Please report any bugs or feature requests to <http://github.com/clintongormley/ConfigMerge/issues>.

AUTHOR

       Clinton Gormley, <clinton@traveljury.com>

COPYRIGHT

       Copyright (C) 2007-2010 by Clinton Gormley

LICENSE

       This  library  is  free  software;  you can redistribute it and/or modify it under the same terms as Perl
       itself, either Perl version 5.8.7 or, at your option, any later version of Perl 5 you may have available.

perl v5.36.0                                       2022-11-19                                 Config::Merge(3pm)