Provided by: libconfig-mvp-perl_2.200013-1_all bug

NAME

       Config::MVP - multivalue-property package-oriented configuration

VERSION

       version 2.200013

SYNOPSIS

       If you want a useful synopsis, consider this code which actually comes from
       Config::MVP::Assembler:

         my $assembler = Config::MVP::Assembler->new;

         # Maybe you want a starting section:
         my $section = $assembler->section_class->new({ name => '_' });
         $assembler->sequence->add_section($section);

         # We'll add some values, which will go to the starting section:
         $assembler->add_value(x => 10);
         $assembler->add_value(y => 20);

         # Change to a new section...
         $assembler->change_section($moniker);

         # ...and add values to that section.
         $assembler->add_value(x => 100);
         $assembler->add_value(y => 200);

       This doesn't make sense?  Well, read on.

       (You can also read the 2009 RJBS Advent Calendar article
       <http://advent.rjbs.manxome.org/2009/2009-12-20.html> on Config::MVP!)

DESCRIPTION

       MVP is a mechanism for loading configuration (or other information) for libraries.  It
       doesn't read a file or a database.  It's a helper for things that do.

       The idea is that you end up with a Config::MVP::Sequence object, and that you can use that
       object to fully configure your library or application.  The sequence will contain a bunch
       of Config::MVP::Section objects, each of which is meant to provide configuration for a
       part of your program.  Most of these sections will be directly related to a Perl library
       that you'll use as a plugin or helper.  Each section will have a name, and every name in
       the sequence will be unique.

       This is a pretty abstract set of behaviors, so we'll provide some more concrete examples
       that should help explain how things work.

PERL VERSION

       This module should work on any version of perl still receiving updates from the Perl 5
       Porters.  This means it should work on any version of perl released in the last two to
       three years.  (That is, if the most recently released version is v5.40, then this module
       should work on both v5.40 and v5.38.)

       Although it may work on older versions of perl, no guarantee is made that the minimum
       required version will not be increased.  The version may be increased for any reason, and
       there is no promise that patches will be accepted to lower the minimum required perl.

EXAMPLE

       Imagine that we've got a program called DeliveryBoy that accepts mail and does stuff with
       it.  The "stuff" is entirely up to the user's configuration.  He can set up plugins that
       will be used on the message.  He writes a config file that's read by
       Config::MVP::Reader::INI, which is a thin wrapper around Config::MVP used to load MVP-
       style config from INI files.

       Here's the user's configuration:

         [Whitelist]
         require_pgp = 1

         file = whitelist-family
         file = whitelist-friends
         file = whitelist-work

         [SpamFilter]
         filterset = standard
         max_score = 5
         action    = bounce

         [SpamFilter / SpamFilter_2]
         filterset = aggressive
         max_score = 5
         action    = tag

         [VerifyPGP]

         [Deliver]
         dest = Maildir

       The user will end up with a sequence with five sections, which we can represent something
       like this:

         { name    => 'Whitelist',
           package => 'DeliveryBoy::Plugin::Whitelist',
           payload => {
             require_pgp => 1,
             files   => [ qw(whitelist-family whitelist-friends whitelist-work) ]
           },
         },
         { name    => 'SpamFilter',
           package => 'DeliveryBoy::Plugin::SpamFilter',
           payload => {
             filterset => 'standard',
             max_score => 5,
             action    => 'bounce',
           }
         },
         { name    => 'SpamFilter_2',
           package => 'DeliveryBoy::Plugin::SpamFilter',
           payload => {
             filterset => 'aggressive',
             max_score => 5,
             action    => 'tag',
           },
         },
         { name    => 'VerifyPGP',
           package => 'DeliveryBoy::Plugin::VerifyPGP',
           payload => { },
         },
         { name    => 'Deliver',
           package => 'DeliveryBoy::Plugin::Deliver',
           payload => { dest => 'Maildir' },
         },

       The INI reader uses Config::MVP::Assembler to build up configuration section by section as
       it goes, so that's how we'll talk about what's going on.

       Every section of the config file was converted into a section in the MVP sequence.  Each
       section has a unique name, which defaults to the name of the INI section.  Each section is
       also associated with a package, which was expanded from the INI section name.  The way
       that names are expanded can be customized by subclassing the assembler.

       Every section also has a payload -- a hashref of settings.  Note that every entry in every
       payload is a simple scalar except for one.  The "files" entry for the Whitelist section is
       an arrayref.  Also, note that while it appears as "files" in the final output, it was
       given as "file" in the input.

       Config::MVP provides a mechanism by which packages can define aliases for configuration
       names and an indication of what names correspond to "multi-value parameters."  (That's
       part of the meaning of the name "MVP.")  When the MVP assembler is told to start a section
       for "Whitelist" it expands the section name, loads the package, and inspects it for
       aliases and multivalue parameters.  Then if multiple entries for a non-multivalue
       parameter are given, an exception can be raised.  Multivalue parameters are always pushed
       onto arrayrefs and non-multivalue parameters are left as found.

   ...so what now?
       So, once our DeliveryBoy program has loaded its configuration, it needs to initialize its
       plugins.  It can do something like the following:

         my $sequence = $deliveryboy->load_config;

         for my $section ($sequence->sections) {
           my $plugin = $section->package->new( $section->payload );
           $deliveryboy->add_plugin( $section->name, $plugin );
         }

       That's it!  In fact, allowing this very, very block of code to load configuration and
       initialize plugins is the goal of Config::MVP.

       The one thing not depicted is the notion of a "root section" that you might expect to see
       in an INI file.  This can be easily handled by starting your assembler off with a pre-
       built section where root settings will end up.  For more information on this, look at the
       docs for the specific components.

WHAT NEXT?

   Making Packages work with MVP
       Any package can be used as part of an MVP section.  Packages can provide some methods to
       help MVP work with them.  It isn't a problem if they are not defined

       mvp_aliases

       This method should return a hashref of name remappings.  For example, if it returned this
       hashref:

         {
           file => 'files',
           path => 'files',
         }

       Then attempting to set either the "file" or "path" setting for the section would actually
       set the "files" setting.

       mvp_multivalue_args

       This method should return a list of setting names that may have multiple values and that
       will always be stored in an arrayref.

   The Assembler
       Config::MVP::Assembler is a state machine that makes it easy to build up your MVP-style
       configuration by firing off a series of events: new section, new setting, etc.  You might
       want to subclass it to change the class of sequence or section that's used or to change
       how section names are expanded into packages.

   Sequences and Sections
       Config::MVP::Sequence and Config::MVP::Section are the two most important classes in MVP.
       They represent the overall configuration and each section of the configuration,
       respectively.  They're both fairly simple classes, and you probably won't need to subclass
       them, but it's easy.

   Examples in the World
       For examples of Config::MVP in use, you can look at Dist::Zilla or App::Addex.

AUTHOR

       Ricardo Signes <cpan@semiotic.systems>

CONTRIBUTORS

       •   Alexandr Ciornii <alexchorny@gmail.com>

       •   George Hartzell <hartzell@alerce.com>

       •   Karen Etheridge <ether@cpan.org>

       •   Kent Fredric <kentfredric@gmail.com>

       •   Philippe Bruhat (BooK) <book@cpan.org>

       •   Ricardo Signes <rjbs@semiotic.systems>

       •   Sven Kirmess <sven.kirmess@kzone.ch>

COPYRIGHT AND LICENSE

       This software is copyright (c) 2022 by Ricardo Signes.

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