1Config::MVP(3) User Contributed Perl Documentation Config::MVP(3)
2
3
4
6 Config::MVP - multivalue-property package-oriented configuration
7
9 version 2.200013
10
12 If you want a useful synopsis, consider this code which actually comes
13 from Config::MVP::Assembler:
14
15 my $assembler = Config::MVP::Assembler->new;
16
17 # Maybe you want a starting section:
18 my $section = $assembler->section_class->new({ name => '_' });
19 $assembler->sequence->add_section($section);
20
21 # We'll add some values, which will go to the starting section:
22 $assembler->add_value(x => 10);
23 $assembler->add_value(y => 20);
24
25 # Change to a new section...
26 $assembler->change_section($moniker);
27
28 # ...and add values to that section.
29 $assembler->add_value(x => 100);
30 $assembler->add_value(y => 200);
31
32 This doesn't make sense? Well, read on.
33
34 (You can also read the 2009 RJBS Advent Calendar article
35 <http://advent.rjbs.manxome.org/2009/2009-12-20.html> on Config::MVP!)
36
38 MVP is a mechanism for loading configuration (or other information) for
39 libraries. It doesn't read a file or a database. It's a helper for
40 things that do.
41
42 The idea is that you end up with a Config::MVP::Sequence object, and
43 that you can use that object to fully configure your library or
44 application. The sequence will contain a bunch of Config::MVP::Section
45 objects, each of which is meant to provide configuration for a part of
46 your program. Most of these sections will be directly related to a
47 Perl library that you'll use as a plugin or helper. Each section will
48 have a name, and every name in the sequence will be unique.
49
50 This is a pretty abstract set of behaviors, so we'll provide some more
51 concrete examples that should help explain how things work.
52
54 This module should work on any version of perl still receiving updates
55 from the Perl 5 Porters. This means it should work on any version of
56 perl released in the last two to three years. (That is, if the most
57 recently released version is v5.40, then this module should work on
58 both v5.40 and v5.38.)
59
60 Although it may work on older versions of perl, no guarantee is made
61 that the minimum required version will not be increased. The version
62 may be increased for any reason, and there is no promise that patches
63 will be accepted to lower the minimum required perl.
64
66 Imagine that we've got a program called DeliveryBoy that accepts mail
67 and does stuff with it. The "stuff" is entirely up to the user's
68 configuration. He can set up plugins that will be used on the message.
69 He writes a config file that's read by Config::MVP::Reader::INI, which
70 is a thin wrapper around Config::MVP used to load MVP-style config from
71 INI files.
72
73 Here's the user's configuration:
74
75 [Whitelist]
76 require_pgp = 1
77
78 file = whitelist-family
79 file = whitelist-friends
80 file = whitelist-work
81
82 [SpamFilter]
83 filterset = standard
84 max_score = 5
85 action = bounce
86
87 [SpamFilter / SpamFilter_2]
88 filterset = aggressive
89 max_score = 5
90 action = tag
91
92 [VerifyPGP]
93
94 [Deliver]
95 dest = Maildir
96
97 The user will end up with a sequence with five sections, which we can
98 represent something like this:
99
100 { name => 'Whitelist',
101 package => 'DeliveryBoy::Plugin::Whitelist',
102 payload => {
103 require_pgp => 1,
104 files => [ qw(whitelist-family whitelist-friends whitelist-work) ]
105 },
106 },
107 { name => 'SpamFilter',
108 package => 'DeliveryBoy::Plugin::SpamFilter',
109 payload => {
110 filterset => 'standard',
111 max_score => 5,
112 action => 'bounce',
113 }
114 },
115 { name => 'SpamFilter_2',
116 package => 'DeliveryBoy::Plugin::SpamFilter',
117 payload => {
118 filterset => 'aggressive',
119 max_score => 5,
120 action => 'tag',
121 },
122 },
123 { name => 'VerifyPGP',
124 package => 'DeliveryBoy::Plugin::VerifyPGP',
125 payload => { },
126 },
127 { name => 'Deliver',
128 package => 'DeliveryBoy::Plugin::Deliver',
129 payload => { dest => 'Maildir' },
130 },
131
132 The INI reader uses Config::MVP::Assembler to build up configuration
133 section by section as it goes, so that's how we'll talk about what's
134 going on.
135
136 Every section of the config file was converted into a section in the
137 MVP sequence. Each section has a unique name, which defaults to the
138 name of the INI section. Each section is also associated with a
139 package, which was expanded from the INI section name. The way that
140 names are expanded can be customized by subclassing the assembler.
141
142 Every section also has a payload -- a hashref of settings. Note that
143 every entry in every payload is a simple scalar except for one. The
144 "files" entry for the Whitelist section is an arrayref. Also, note
145 that while it appears as "files" in the final output, it was given as
146 "file" in the input.
147
148 Config::MVP provides a mechanism by which packages can define aliases
149 for configuration names and an indication of what names correspond to
150 "multi-value parameters." (That's part of the meaning of the name
151 "MVP.") When the MVP assembler is told to start a section for
152 "Whitelist" it expands the section name, loads the package, and
153 inspects it for aliases and multivalue parameters. Then if multiple
154 entries for a non-multivalue parameter are given, an exception can be
155 raised. Multivalue parameters are always pushed onto arrayrefs and
156 non-multivalue parameters are left as found.
157
158 ...so what now?
159 So, once our DeliveryBoy program has loaded its configuration, it needs
160 to initialize its plugins. It can do something like the following:
161
162 my $sequence = $deliveryboy->load_config;
163
164 for my $section ($sequence->sections) {
165 my $plugin = $section->package->new( $section->payload );
166 $deliveryboy->add_plugin( $section->name, $plugin );
167 }
168
169 That's it! In fact, allowing this very, very block of code to load
170 configuration and initialize plugins is the goal of Config::MVP.
171
172 The one thing not depicted is the notion of a "root section" that you
173 might expect to see in an INI file. This can be easily handled by
174 starting your assembler off with a pre-built section where root
175 settings will end up. For more information on this, look at the docs
176 for the specific components.
177
179 Making Packages work with MVP
180 Any package can be used as part of an MVP section. Packages can
181 provide some methods to help MVP work with them. It isn't a problem if
182 they are not defined
183
184 mvp_aliases
185
186 This method should return a hashref of name remappings. For example,
187 if it returned this hashref:
188
189 {
190 file => 'files',
191 path => 'files',
192 }
193
194 Then attempting to set either the "file" or "path" setting for the
195 section would actually set the "files" setting.
196
197 mvp_multivalue_args
198
199 This method should return a list of setting names that may have
200 multiple values and that will always be stored in an arrayref.
201
202 The Assembler
203 Config::MVP::Assembler is a state machine that makes it easy to build
204 up your MVP-style configuration by firing off a series of events: new
205 section, new setting, etc. You might want to subclass it to change the
206 class of sequence or section that's used or to change how section names
207 are expanded into packages.
208
209 Sequences and Sections
210 Config::MVP::Sequence and Config::MVP::Section are the two most
211 important classes in MVP. They represent the overall configuration and
212 each section of the configuration, respectively. They're both fairly
213 simple classes, and you probably won't need to subclass them, but it's
214 easy.
215
216 Examples in the World
217 For examples of Config::MVP in use, you can look at Dist::Zilla or
218 App::Addex.
219
221 Ricardo Signes <cpan@semiotic.systems>
222
224 • Alexandr Ciornii <alexchorny@gmail.com>
225
226 • George Hartzell <hartzell@alerce.com>
227
228 • Karen Etheridge <ether@cpan.org>
229
230 • Kent Fredric <kentfredric@gmail.com>
231
232 • Philippe Bruhat (BooK) <book@cpan.org>
233
234 • Ricardo Signes <rjbs@semiotic.systems>
235
236 • Sven Kirmess <sven.kirmess@kzone.ch>
237
239 This software is copyright (c) 2022 by Ricardo Signes.
240
241 This is free software; you can redistribute it and/or modify it under
242 the same terms as the Perl 5 programming language system itself.
243
244
245
246perl v5.38.0 2023-07-20 Config::MVP(3)