This file is indexed.

/usr/share/perl5/Config/MVP.pm is in libconfig-mvp-perl 2.200010-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
package Config::MVP;
# ABSTRACT: multivalue-property package-oriented configuration
$Config::MVP::VERSION = '2.200010';
use strict;
use warnings;

#pod =head1 SYNOPSIS
#pod
#pod If you want a useful synopsis, consider this code which actually comes from
#pod L<Config::MVP::Assembler|Config::MVP::Assembler>:
#pod
#pod   my $assembler = Config::MVP::Assembler->new;
#pod
#pod   # Maybe you want a starting section:
#pod   my $section = $assembler->section_class->new({ name => '_' });
#pod   $assembler->sequence->add_section($section);
#pod
#pod   # We'll add some values, which will go to the starting section:
#pod   $assembler->add_value(x => 10);
#pod   $assembler->add_value(y => 20);
#pod
#pod   # Change to a new section...
#pod   $assembler->change_section($moniker);
#pod
#pod   # ...and add values to that section.
#pod   $assembler->add_value(x => 100);
#pod   $assembler->add_value(y => 200);
#pod
#pod This doesn't make sense?  Well, read on.
#pod
#pod =head1 DESCRIPTION
#pod
#pod MVP is a mechanism for loading configuration (or other information) for
#pod libraries.  It doesn't read a file or a database.  It's a helper for things
#pod that do.
#pod
#pod The idea is that you end up with a
#pod L<Config::MVP::Sequence|Config::MVP::Sequence> object, and that you can use
#pod that object to fully configure your library or application.  The sequence will
#pod contain a bunch of L<Config::MVP::Section|Config::MVP::Section> objects, each
#pod of which is meant to provide configuration for a part of your program.  Most of
#pod these sections will be directly related to a Perl library that you'll use as a
#pod plugin or helper.  Each section will have a name, and every name in the
#pod sequence will be unique.
#pod
#pod This is a pretty abstract set of behaviors, so we'll provide some more concrete
#pod examples that should help explain how things work.
#pod
#pod =head1 EXAMPLE
#pod
#pod Imagine that we've got a program called DeliveryBoy that accepts mail and does
#pod stuff with it.  The "stuff" is entirely up to the user's configuration.  He can
#pod set up plugins that will be used on the message.  He writes a config file that's
#pod read by L<Config::MVP::Reader::INI|Config::MVP::Reader::INI>, which is a thin
#pod wrapper around Config::MVP used to load MVP-style config from F<INI> files.
#pod
#pod Here's the user's configuration:
#pod
#pod   [Whitelist]
#pod   require_pgp = 1
#pod
#pod   file = whitelist-family
#pod   file = whitelist-friends
#pod   file = whitelist-work
#pod
#pod   [SpamFilter]
#pod   filterset = standard
#pod   max_score = 5
#pod   action    = bounce
#pod
#pod   [SpamFilter / SpamFilter_2]
#pod   filterset = aggressive
#pod   max_score = 5
#pod   action    = tag
#pod
#pod   [VerifyPGP]
#pod
#pod   [Deliver]
#pod   dest = Maildir
#pod
#pod The user will end up with a sequence with five sections, which we can represent
#pod something like this:
#pod
#pod   { name    => 'Whitelist',
#pod     package => 'DeliveryBoy::Plugin::Whitelist',
#pod     payload => {
#pod       require_pgp => 1,
#pod       files   => [ qw(whitelist-family whitelist-friends whitelist-work) ]
#pod     },
#pod   },
#pod   { name    => 'SpamFilter',
#pod     package => 'DeliveryBoy::Plugin::SpamFilter',
#pod     payload => {
#pod       filterset => 'standard',
#pod       max_score => 5,
#pod       action    => 'bounce',
#pod     }
#pod   },
#pod   { name    => 'SpamFilter_2',
#pod     package => 'DeliveryBoy::Plugin::SpamFilter',
#pod     payload => {
#pod       filterset => 'aggressive',
#pod       max_score => 5,
#pod       action    => 'tag',
#pod     },
#pod   },
#pod   { name    => 'VerifyPGP',
#pod     package => 'DeliveryBoy::Plugin::VerifyPGP',
#pod     payload => { },
#pod   },
#pod   { name    => 'Deliver',
#pod     package => 'DeliveryBoy::Plugin::Deliver',
#pod     payload => { dest => 'Maildir' },
#pod   },
#pod
#pod The INI reader uses L<Config::MVP::Assembler|Config::MVP::Assembler> to build
#pod up configuration section by section as it goes, so that's how we'll talk about
#pod what's going on.
#pod
#pod Every section of the config file was converted into a section in the MVP
#pod sequence.  Each section has a unique name, which defaults to the name of the
#pod INI section.  Each section is also associated with a package, which was
#pod expanded from the INI section name.  The way that names are expanded can be
#pod customized by subclassing the assembler.
#pod
#pod Every section also has a payload -- a hashref of settings.  Note that every
#pod entry in every payload is a simple scalar except for one.  The C<files> entry
#pod for the Whitelist section is an arrayref.  Also, note that while it appears as
#pod C<files> in the final output, it was given as C<file> in the input.
#pod
#pod Config::MVP provides a mechanism by which packages can define aliases for
#pod configuration names and an indication of what names correspond to "multi-value
#pod parameters."  (That's part of the meaning of the name "MVP.")  When the MVP
#pod assembler is told to start a section for C<Whitelist> it expands the section
#pod name, loads the package, and inspects it for aliases and multivalue parameters.
#pod Then if multiple entries for a non-multivalue parameter are given, an exception
#pod can be raised.  Multivalue parameters are always pushed onto arrayrefs and
#pod non-multivalue parameters are left as found.
#pod
#pod =head2 ...so what now?
#pod
#pod So, once our DeliveryBoy program has loaded its configuration, it needs to
#pod initialize its plugins.  It can do something like the following:
#pod
#pod   my $sequence = $deliveryboy->load_config;
#pod
#pod   for my $section ($sequence->sections) {
#pod     my $plugin = $section->package->new( $section->payload );
#pod     $deliveryboy->add_plugin( $section->name, $plugin );
#pod   }
#pod
#pod That's it!  In fact, allowing this very, very block of code to load
#pod configuration and initialize plugins is the goal of Config::MVP.
#pod
#pod The one thing not depicted is the notion of a "root section" that you might
#pod expect to see in an INI file.  This can be easily handled by starting your
#pod assembler off with a pre-built section where root settings will end up.  For
#pod more information on this, look at the docs for the specific components.
#pod
#pod =head1 WHAT NEXT?
#pod
#pod =head2 Making Packages work with MVP
#pod
#pod Any package can be used as part of an MVP section.  Packages can provide some
#pod methods to help MVP work with them.  It isn't a problem if they are not defined
#pod
#pod =head3 mvp_aliases
#pod
#pod This method should return a hashref of name remappings.  For example, if it
#pod returned this hashref:
#pod
#pod   {
#pod     file => 'files',
#pod     path => 'files',
#pod   }
#pod
#pod Then attempting to set either the "file" or "path" setting for the section
#pod would actually set the "files" setting.
#pod
#pod =head3 mvp_multivalue_args
#pod
#pod This method should return a list of setting names that may have multiple values
#pod and that will always be stored in an arrayref.
#pod
#pod =head2 The Assembler
#pod
#pod L<Config::MVP::Assembler|Config::MVP::Assembler> is a state machine that makes
#pod it easy to build up your MVP-style configuration by firing off a series of
#pod events: new section, new setting, etc.  You might want to subclass it to change
#pod the class of sequence or section that's used or to change how section names are
#pod expanded into packages.
#pod
#pod =head2 Sequences and Sections
#pod
#pod L<Config::MVP::Sequence|Config::MVP::Sequence> and
#pod L<Config::MVP::Section|Config::MVP::Section> are the two most important classes
#pod in MVP.  They represent the overall configuration and each section of the
#pod configuration, respectively.  They're both fairly simple classes, and you
#pod probably won't need to subclass them, but it's easy.
#pod
#pod =head2 Examples in the World
#pod
#pod For examples of Config::MVP in use, you can look at L<Dist::Zilla|Dist::Zilla>
#pod or L<App::Addex|App::Addex>.
#pod
#pod =cut

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

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

=head1 VERSION

version 2.200010

=head1 SYNOPSIS

If you want a useful synopsis, consider this code which actually comes from
L<Config::MVP::Assembler|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.

=head1 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
L<Config::MVP::Sequence|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 L<Config::MVP::Section|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.

=head1 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 L<Config::MVP::Reader::INI|Config::MVP::Reader::INI>, which is a thin
wrapper around Config::MVP used to load MVP-style config from F<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 L<Config::MVP::Assembler|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 C<files> entry
for the Whitelist section is an arrayref.  Also, note that while it appears as
C<files> in the final output, it was given as C<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 C<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.

=head2 ...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.

=head1 WHAT NEXT?

=head2 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

=head3 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.

=head3 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.

=head2 The Assembler

L<Config::MVP::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.

=head2 Sequences and Sections

L<Config::MVP::Sequence|Config::MVP::Sequence> and
L<Config::MVP::Section|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.

=head2 Examples in the World

For examples of Config::MVP in use, you can look at L<Dist::Zilla|Dist::Zilla>
or L<App::Addex|App::Addex>.

=head1 AUTHOR

Ricardo Signes <rjbs@cpan.org>

=head1 CONTRIBUTORS

=for stopwords Alexandr Ciornii George Hartzell Karen Etheridge Kent Fredric Philippe Bruhat (BooK)

=over 4

=item *

Alexandr Ciornii <alexchorny@gmail.com>

=item *

George Hartzell <hartzell@alerce.com>

=item *

Karen Etheridge <ether@cpan.org>

=item *

Kent Fredric <kentfredric@gmail.com>

=item *

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

=back

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 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.

=cut