.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Config::Model::Value 3pm" .TH Config::Model::Value 3pm "2023-08-19" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Config::Model::Value \- Strongly typed configuration value .SH "VERSION" .IX Header "VERSION" version 2.153 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Config::Model; \& \& # define configuration tree object \& my $model = Config::Model\->new; \& $model \->create_config_class ( \& name => "MyClass", \& \& element => [ \& \& [qw/foo bar/] => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& description => \*(Aqfoobar\*(Aq, \& } \& , \& country => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, \& choice => [qw/France US/], \& description => \*(Aqbig countries\*(Aq, \& } \& , \& ], \& ) ; \& \& my $inst = $model\->instance(root_class_name => \*(AqMyClass\*(Aq ); \& \& my $root = $inst\->config_root ; \& \& # put data \& $root\->load( steps => \*(Aqfoo=FOO country=US\*(Aq ); \& \& print $root\->report ; \& # foo = FOO \& # DESCRIPTION: foobar \& # \& # country = US \& # DESCRIPTION: big countries .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This class provides a way to specify configuration value with the following properties: .IP "\(bu" 4 Strongly typed scalar: the value can either be an enumerated type, a boolean, a number, an integer or a string .IP "\(bu" 4 default parameter: a value can have a default value specified during the construction. This default value is written in the target configuration file. (\f(CW\*(C`default\*(C'\fR parameter) .IP "\(bu" 4 upstream default parameter: specifies a default value that is used by the application when no information is provided in the configuration file. This upstream_default value is not written in the configuration files. Only the \f(CW\*(C`fetch_standard\*(C'\fR method returns the builtin value. This parameter was previously referred as \&\f(CW\*(C`built_in\*(C'\fR value. This may be used for audit purpose. (\f(CW\*(C`upstream_default\*(C'\fR parameter) .IP "\(bu" 4 mandatory value: reading a mandatory value raises an exception if the value is not specified (i.e is \f(CW\*(C`undef\*(C'\fR or empty string) and has no default value. .IP "\(bu" 4 dynamic change of property: A slave value can be registered to another master value so that the properties of the slave value can change according to the value of the master value. For instance, paper size value can be 'letter' for country '\s-1US\s0' and 'A4' for country 'France'. .IP "\(bu" 4 A reference to the Id of a hash of list element. In other word, the value is an enumerated type where the possible values (choice) is defined by the existing keys of a has element somewhere in the tree. See \&\*(L"Value Reference\*(R". .SH "Default values" .IX Header "Default values" There are several kind of default values. They depend on where these values are defined (or found). .PP From the lowest default level to the \*(L"highest\*(R": .IP "\(bu" 4 \&\f(CW\*(C`upstream_default\*(C'\fR: The value is known in the application, but is not written in the configuration file. .IP "\(bu" 4 \&\f(CW\*(C`layered\*(C'\fR: The value is known by the application through another mean (e.g. an included configuration file), but is not written in the configuration file. .IP "\(bu" 4 \&\f(CW\*(C`default\*(C'\fR: The value is known by the model, but not by the application. This value must be written in the configuration file. .IP "\(bu" 4 \&\f(CW\*(C`computed\*(C'\fR: The value is computed from other configuration elements. This value must be written in the configuration file. .IP "\(bu" 4 \&\f(CW\*(C`preset\*(C'\fR: The value is not known by the model or by the application. But it can be found by an automatic program and stored while the configuration Config::Model::Instance is in preset mode .PP Then there is the value entered by the user. This overrides all kind of \*(L"default\*(R" value. .PP The fetch_standard function returns the \*(L"highest\*(R" level of default value, but does not return a custom value, i.e. a value entered by the user. .SH "Constructor" .IX Header "Constructor" Value object should not be created directly. .SH "Value model declaration" .IX Header "Value model declaration" A leaf element must be declared with the following parameters: .IP "value_type" 4 .IX Item "value_type" Either \f(CW\*(C`boolean\*(C'\fR, \f(CW\*(C`enum\*(C'\fR, \f(CW\*(C`integer\*(C'\fR, \f(CW\*(C`number\*(C'\fR, \&\f(CW\*(C`uniline\*(C'\fR, \f(CW\*(C`string\*(C'\fR, \f(CW\*(C`file\*(C'\fR, \f(CW\*(C`dir\*(C'\fR. Mandatory. See \*(L"Value types\*(R". .IP "default" 4 .IX Item "default" Specify the default value (optional) .IP "upstream_default" 4 .IX Item "upstream_default" Specify a built in default value (optional). I.e a value known by the application which does not need to be written in the configuration file. .IP "write_as" 4 .IX Item "write_as" Array ref. Reserved for boolean value. Specify how to write a boolean value. Default is \f(CW\*(C`[0,1]\*(C'\fR which may not be the most readable. \f(CW\*(C`write_as\*(C'\fR can be specified as \f(CW\*(C`[\*(Aqfalse\*(Aq,\*(Aqtrue\*(Aq]\*(C'\fR or \f(CW\*(C`[\*(Aqno\*(Aq,\*(Aqyes\*(Aq]\*(C'\fR. .IP "compute" 4 .IX Item "compute" Computes a value according to a formula and other values. By default a computed value cannot be set. See Config::Model::ValueComputer for computed value declaration. .IP "migrate_from" 4 .IX Item "migrate_from" This is a special parameter to cater for smooth configuration upgrade. This parameter can be used to copy the value of a deprecated parameter to its replacement. See \*(L"Upgrade\*(R" for details. .IP "convert => [uc | lc ]" 4 .IX Item "convert => [uc | lc ]" When stored, the value is converted to uppercase (uc) or lowercase (lc). .IP "min" 4 .IX Item "min" Specify the minimum value (optional, only for integer, number) .IP "max" 4 .IX Item "max" Specify the maximum value (optional, only for integer, number) .IP "mandatory" 4 .IX Item "mandatory" Set to 1 if the configuration value \fBmust\fR be set by the configuration user (default: 0) .IP "choice" 4 .IX Item "choice" Array ref of the possible value of an enum. Example : .Sp .Vb 1 \& choice => [ qw/foo bar/] .Ve .IP "match" 4 .IX Item "match" Perl regular expression. The value is matched with the regex to assert its validity. Example \f(CW\*(C`match => \*(Aq^foo\*(Aq\*(C'\fR means that the parameter value must begin with \*(L"foo\*(R". Valid only for \f(CW\*(C`string\*(C'\fR or \&\f(CW\*(C`uniline\*(C'\fR values. .IP "warn_if_match" 4 .IX Item "warn_if_match" Hash ref. Keys are made of Perl regular expression. The value can specify a warning message (leave empty or undefined for a default warning message) and instructions to fix the value. A warning is issued when the value matches the passed regular expression. Valid only for \&\f(CW\*(C`string\*(C'\fR or \f(CW\*(C`uniline\*(C'\fR values. The fix instructions is evaluated when apply_fixes is called. \f(CW$_\fR contains the value to fix. \&\f(CW$_\fR is stored as the new value once the instructions are done. \&\f(CW$self\fR contains the value object. Use with care. .Sp In the example below, any value matching 'foo' is converted in uppercase: .Sp .Vb 10 \& warn_if_match => { \& \*(Aqfoo\*(Aq => { \& fix => \*(Aquc;\*(Aq, \& msg => \*(Aqvalue $_ contains foo\*(Aq \& }, \& \*(AqBAR\*(Aq => { \& fix =>\*(Aqlc;\*(Aq, \& msg => \*(Aqvalue $_ contains BAR\*(Aq \& } \& }, .Ve .Sp The tests are done in alphabetical order. In the example above, \f(CW\*(C`BAR\*(C'\fR test is done before \f(CW\*(C`foo\*(C'\fR test. .Sp \&\f(CW$_\fR is substituted with the bad value when the message is generated. \f(CW$std_value\fR is substituted with the standard value (i.e the preset, computed or default value). .IP "warn_unless_match" 4 .IX Item "warn_unless_match" Hash ref like above. A warning is issued when the value does not match the passed regular expression. Valid only for \f(CW\*(C`string\*(C'\fR or \&\f(CW\*(C`uniline\*(C'\fR values. .IP "warn" 4 .IX Item "warn" String. Issue a warning to user with the specified string any time a value is set or read. .IP "warn_if" 4 .IX Item "warn_if" A bit like \f(CW\*(C`warn_if_match\*(C'\fR. The hash key is not a regexp but a label to help users. The hash ref contains some Perl code that is evaluated to perform the test. A warning is issued if the given code returns true. .Sp \&\f(CW$_\fR contains the value to check. \f(CW$self\fR contains the \&\f(CW\*(C`Config::Model::Value\*(C'\fR object (use with care). .Sp The example below warns if value contains a number: .Sp .Vb 7 \& warn_if => { \& warn_test => { \& code => \*(Aqdefined $_ && /\ed/;\*(Aq, \& msg => \*(Aqvalue $_ should not have numbers\*(Aq, \& fix => \*(Aqs/\ed//g;\*(Aq \& } \& }, .Ve .Sp Hash key is used in warning message when \f(CW\*(C`msg\*(C'\fR is not set: .Sp .Vb 5 \& warn_if => { \& \*(Aqshould begin with foo\*(Aq => { \& code => \*(Aqdefined && /^foo/\*(Aq \& } \& } .Ve .Sp Any operation or check on file must be done with \f(CW\*(C`file\*(C'\fR sub (otherwise tests will break). This sub returns a Path::Tiny object that can be used to perform checks. For instance: .Sp .Vb 5 \& warn_if => { \& warn_test => { \& code => \*(Aqnot file($_)\->exists\*(Aq, \& msg => \*(Aqfile $_ should exist\*(Aq \& } .Ve .IP "warn_unless" 4 .IX Item "warn_unless" Like \f(CW\*(C`warn_if\*(C'\fR, but issue a warning when the given \f(CW\*(C`code\*(C'\fR returns false. .Sp The example below warns unless the value points to an existing directory: .Sp .Vb 5 \& warn_unless => { \& \*(Aqmissing dir\*(Aq => { \& code => \*(Aq\-d\*(Aq, \& fix => "system(mkdir $_);" } \& } .Ve .IP "assert" 4 .IX Item "assert" Like \f(CW\*(C`warn_if\*(C'\fR. Except that returned value triggers an error when the given code returns false: .Sp .Vb 7 \& assert => { \& test_nb => { \& code => \*(Aqdefined $_ && /\ed/;\*(Aq, \& msg => \*(Aqshould not have numbers\*(Aq, \& fix => \*(Aqs/\ed//g;\*(Aq \& } \& }, .Ve .Sp hash key can also be used to generate error message when \f(CW\*(C`msg\*(C'\fR parameter is not set. .IP "grammar" 4 .IX Item "grammar" Setup a Parse::RecDescent grammar to perform validation. .Sp If the grammar does not start with a \*(L"check\*(R" rule (i.e does not start with \*(L"check: \*(R"), the first line of the grammar is modified to add \*(L"check\*(R" rule and this rules is set up so the entire value must match the passed grammar. .Sp I.e. the grammar: .Sp .Vb 3 \& token (oper token)(s?) \& oper: \*(Aqand\*(Aq | \*(Aqor\*(Aq \& token: \*(AqApache\*(Aq | \*(AqCC\-BY\*(Aq | \*(AqPerl\*(Aq .Ve .Sp is changed to .Sp .Vb 3 \& check: token (oper token)(s?) /^\eZ/ {$return = 1;} \& oper: \*(Aqand\*(Aq | \*(Aqor\*(Aq \& token: \*(AqApache\*(Aq | \*(AqCC\-BY\*(Aq | \*(AqPerl\*(Aq .Ve .Sp The rule is called with Value object and a string reference. So, in the actions you may need to define, you can call the value object as \&\f(CW$arg[0]\fR, store error message in \f(CW\*(C`${$arg[1]}}\*(C'\fR and store warnings in \&\f(CW\*(C`${$arg[2]}}\*(C'\fR. .IP "replace" 4 .IX Item "replace" Hash ref. Used for enum to substitute one value with another. This parameter must be used to enable user to upgrade a configuration with obsolete values. For instance, if the value \f(CW\*(C`foo\*(C'\fR is obsolete and replaced by \f(CW\*(C`foo_better\*(C'\fR, you must declare: .Sp .Vb 1 \& replace => { foo => \*(Aqfoo_better\*(Aq } .Ve .Sp The hash key can also be a regular expression for wider range replacement. The regexp must match the whole value: .Sp .Vb 1 \& replace => ( \*(Aqfoo.*\*(Aq => \*(Aqbetter_foo\*(Aq } .Ve .Sp In this case, a value is replaced by \f(CW\*(C`better_foo\*(C'\fR when the \&\f(CW\*(C`/^foo.*$/\*(C'\fR regexp matches. .IP "replace_follow" 4 .IX Item "replace_follow" Path specifying a hash of value element in the configuration tree. The hash if used in a way similar to the \f(CW\*(C`replace\*(C'\fR parameter. In this case, the replacement is not coded in the model but specified by the configuration. .IP "refer_to" 4 .IX Item "refer_to" Specify a path to an id element used as a reference. See Value Reference for details. .IP "computed_refer_to" 4 .IX Item "computed_refer_to" Specify a path to an id element used as a computed reference. See \&\*(L"Value Reference\*(R" for details. .IP "warp" 4 .IX Item "warp" See section below: \*(L"Warp: dynamic value configuration\*(R". .IP "help" 4 .IX Item "help" You may provide detailed description on possible values with a hash ref. Example: .Sp help => { oui => \*(L"French for 'yes'\*(R", non => \*(L"French for 'no'\*(R"} .Sp The key of help is used as a regular expression to find the help text applicable to a value. These regexp are tried from the longest to the shortest and are matched from the beginning of the string. The key "\f(CW\*(C`.\*(C'\fR\*(L" or \*(R"\f(CW\*(C`.*\*(C'\fR" are fallback used last. .Sp For instance: .Sp .Vb 5 \& help => { \& \*(Aqfoobar\*(Aq => \*(Aqhelp for values matching /^foobar/\*(Aq, \& \*(Aqfoo\*(Aq => \*(Aqhelp for values matching /^foo/ but not /^foobar/ (used above)\*(Aq, \& \*(Aq.\*(Aq => \*(Aqhelp for all other values\*(Aq \& } .Ve .SS "Value types" .IX Subsection "Value types" This modules can check several value types: .ie n .IP """boolean""" 4 .el .IP "\f(CWboolean\fR" 4 .IX Item "boolean" Accepts values \f(CW1\fR or \f(CW0\fR, \f(CW\*(C`yes\*(C'\fR or \f(CW\*(C`no\*(C'\fR, \f(CW\*(C`true\*(C'\fR or \f(CW\*(C`false\*(C'\fR, and empty string. The value read back is always \f(CW1\fR or \f(CW0\fR. .ie n .IP """enum""" 4 .el .IP "\f(CWenum\fR" 4 .IX Item "enum" Enum choices must be specified by the \f(CW\*(C`choice\*(C'\fR parameter. .ie n .IP """integer""" 4 .el .IP "\f(CWinteger\fR" 4 .IX Item "integer" Enable positive or negative integer .ie n .IP """number""" 4 .el .IP "\f(CWnumber\fR" 4 .IX Item "number" The value can be a decimal number .ie n .IP """uniline""" 4 .el .IP "\f(CWuniline\fR" 4 .IX Item "uniline" A one line string. I.e without \*(L"\en\*(R" in it. .ie n .IP """string""" 4 .el .IP "\f(CWstring\fR" 4 .IX Item "string" Actually, no check is performed with this type. .ie n .IP """reference""" 4 .el .IP "\f(CWreference\fR" 4 .IX Item "reference" Like an \f(CW\*(C`enum\*(C'\fR where the possible values (aka choice) is defined by another location if the configuration tree. See \*(L"Value Reference\*(R". .ie n .IP """file""" 4 .el .IP "\f(CWfile\fR" 4 .IX Item "file" A file name or path. A warning is issued if the file does not exists (or is a directory) .ie n .IP """dir""" 4 .el .IP "\f(CWdir\fR" 4 .IX Item "dir" A directory name or path. A warning is issued if the directory does not exists (or is a plain file) .SH "Warp: dynamic value configuration" .IX Header "Warp: dynamic value configuration" The Warp functionality enable a \f(CW\*(C`Value\*(C'\fR object to change its properties (i.e. default value or its type) dynamically according to the value of another \f(CW\*(C`Value\*(C'\fR object locate elsewhere in the configuration tree. (See Config::Model::Warper for an explanation on warp mechanism). .PP For instance if you declare 2 \f(CW\*(C`Value\*(C'\fR element this way: .PP .Vb 10 \& $model \->create_config_class ( \& name => "TV_config_class", \& element => [ \& country => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, \& choice => [qw/US Europe Japan/] \& } , \& tv_standard => { # this example is getting old... \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, \& choice => [ qw/PAL NTSC SECAM/ ] \& warp => { \& follow => { \& # this points to the warp master \& c => \*(Aq\- country\*(Aq \& }, \& rules => { \& \*(Aq$c eq "US"\*(Aq => { \& default => \*(AqNTSC\*(Aq \& }, \& \*(Aq$c eq "France"\*(Aq => { \& default => \*(AqSECAM\*(Aq \& }, \& \*(Aq$c eq "Japan"\*(Aq => { \& default => \*(AqNTSC\*(Aq \& }, \& \*(Aq$c eq "Europe"\*(Aq => { \& default => \*(AqPAL\*(Aq \& }, \& } \& } \& } , \& ] \& ); .Ve .PP Setting \f(CW\*(C`country\*(C'\fR element to \f(CW\*(C`US\*(C'\fR means that \f(CW\*(C`tv_standard\*(C'\fR has a default value set to \f(CW\*(C`NTSC\*(C'\fR by the warp mechanism. .PP Likewise, the warp mechanism enables you to dynamically change the possible values of an enum element: .PP .Vb 10 \& state => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, # example is admittedly silly \& warp => { \& follow => { \& c => \*(Aq\- country\*(Aq \& }, \& rules => { \& \*(Aq$c eq "US"\*(Aq => { \& choice => [\*(AqKansas\*(Aq, \*(AqTexas\*(Aq ] \& }, \& \*(Aq$c eq "Europe"\*(Aq => { \& choice => [\*(AqFrance\*(Aq, \*(AqSpain\*(Aq ] \& }, \& \*(Aq$c eq "Japan"\*(Aq => { \& choice => [\*(AqHonshu\*(Aq, \*(AqHokkaido\*(Aq ] \& } \& } \& } \& } .Ve .SS "Cascaded warping" .IX Subsection "Cascaded warping" Warping value can be cascaded: \f(CW\*(C`A\*(C'\fR can be warped by \f(CW\*(C`B\*(C'\fR which can be warped by \f(CW\*(C`C\*(C'\fR. But this feature should be avoided since it can lead to a model very hard to debug. Bear in mind that: .IP "\(bu" 4 Warp loops are not detected and end up in \*(L"deep recursion subroutine\*(R" failures. .IP "\(bu" 4 avoid \*(L"diamond\*(R" shaped warp dependencies: the results depends on the order of the warp algorithm which can be unpredictable in this case .IP "\(bu" 4 The keys declared in the warp rules (\f(CW\*(C`US\*(C'\fR, \f(CW\*(C`Europe\*(C'\fR and \f(CW\*(C`Japan\*(C'\fR in the example above) cannot be checked at start time against the warp master \f(CW\*(C`Value\*(C'\fR. So a wrong warp rule key is silently ignored during start up and fails at run time. .SH "Value Reference" .IX Header "Value Reference" To set up an enumerated value where the possible choice depends on the key of a Config::Model::AnyId object, you must: .IP "\(bu" 4 Set \f(CW\*(C`value_type\*(C'\fR to \f(CW\*(C`reference\*(C'\fR. .IP "\(bu" 4 Specify the \f(CW\*(C`refer_to\*(C'\fR or \f(CW\*(C`computed_refer_to\*(C'\fR parameter. See refer_to parameter. .PP In this case, a \f(CW\*(C`IdElementReference\*(C'\fR object is created to handle the relation between this value object and the referred Id. See Config::Model::IdElementReference for details. .SH "Introspection methods" .IX Header "Introspection methods" The following methods returns the current value of the parameter of the value object (as declared in the model unless they were warped): .IP "min" 4 .IX Item "min" .PD 0 .IP "max" 4 .IX Item "max" .IP "mandatory" 4 .IX Item "mandatory" .IP "choice" 4 .IX Item "choice" .IP "convert" 4 .IX Item "convert" .IP "value_type" 4 .IX Item "value_type" .IP "default" 4 .IX Item "default" .IP "upstream_default" 4 .IX Item "upstream_default" .IP "index_value" 4 .IX Item "index_value" .IP "element_name" 4 .IX Item "element_name" .PD .SS "name" .IX Subsection "name" Returns the object name. .SS "get_type" .IX Subsection "get_type" Returns \f(CW\*(C`leaf\*(C'\fR. .SS "can_store" .IX Subsection "can_store" Returns true if the value object can be assigned to. Return 0 for a read-only value (i.e. a computed value with no override allowed). .SS "get_choice" .IX Subsection "get_choice" Query legal values (only for enum types). Return an array (possibly empty). .SS "get_help" .IX Subsection "get_help" With a parameter, returns the help string applicable to the passed value or undef. .PP Without parameter returns a hash ref that contains all the help strings. .SS "get_info" .IX Subsection "get_info" Returns a list of information related to the value, like value type, default value. This should be used to provide some debug information to the user. .PP For instance, \f(CW\*(C`$val\-\*(C'\fRget\-info> may return: .PP .Vb 1 \& [ \*(Aqtype: string\*(Aq, \*(Aqmandatory: yes\*(Aq ] .Ve .SS "error_msg" .IX Subsection "error_msg" Returns the error messages of this object (if any) .SS "warning_msg" .IX Subsection "warning_msg" Returns warning concerning this value. Returns a list in list context and a string in scalar context. .SS "check_value" .IX Subsection "check_value" Parameters: \f(CW\*(C`( value )\*(C'\fR .PP Check the consistency of the value. .PP \&\f(CW\*(C`check_value\*(C'\fR also accepts named parameters: .IP "value" 4 .IX Item "value" .PD 0 .IP "quiet" 4 .IX Item "quiet" .PD When non null, check does not try to get extra information from the tree. This is required in some cases to avoid loops in check, get_info, get_warp_info, re-check ... .PP In scalar context, return 0 or 1. .PP In array context, return an empty array when no error was found. In case of errors, returns an array of error strings that should be shown to the user. .SS "has_fixes" .IX Subsection "has_fixes" Returns the number of fixes that can be applied to the current value. .SS "apply_fixes" .IX Subsection "apply_fixes" Applies the fixes to suppress the current warnings. .SS "check" .IX Subsection "check" Parameters: \f(CW\*(C`( [ value => foo ] )\*(C'\fR .PP Like \*(L"check_value\*(R". .PP Also displays warnings on \s-1STDOUT\s0 unless \f(CW\*(C`silent\*(C'\fR parameter is set to 1. In this case,user is expected to retrieve them with \&\*(L"warning_msg\*(R". .PP Without \f(CW\*(C`value\*(C'\fR argument, this method checks the value currently stored. .SS "is_bad_mode" .IX Subsection "is_bad_mode" Accept a mode parameter. This function checks if the mode is accepted by \*(L"fetch\*(R" method. Returns an error message if not. For instance: .PP .Vb 3 \& if (my $err = $val\->is_bad_mode(\*(Aqfoo\*(Aq)) { \& croak "my_function: $err"; \& } .Ve .PP This method is intented as a helper to avoid duplicating the list of accepted modes for functions that want to wrap fetch methods (like Config::Model::Dumper or Config::Model::DumpAsData) .SH "Information management" .IX Header "Information management" .SS "store" .IX Subsection "store" Parameters: \f(CW\*(C`( $value )\*(C'\fR or \f(CW\*(C`value => ..., check => yes|no|skip ), silent => 0|1\*(C'\fR .PP Store value in leaf element. \f(CW\*(C`check\*(C'\fR parameter can be used to skip validation check (default is 'yes'). \&\f(CW\*(C`silent\*(C'\fR can be used to suppress warnings. .PP Optional \f(CW\*(C`callback\*(C'\fR is now deprecated. .SS "clear" .IX Subsection "clear" Clear the stored value. Further read returns the default value (or computed or migrated value). .SS "load_data" .IX Subsection "load_data" Parameters: \f(CW\*(C`( $value )\*(C'\fR .PP Called with the same parameters are \f(CW\*(C`store\*(C'\fR method. .PP Load scalar data. Data is forwarded to \*(L"store\*(R" after checking that the passed value is not a reference. .SS "fetch_custom" .IX Subsection "fetch_custom" Returns the stored value if this value is different from a standard setting or built in setting. In other words, returns undef if the stored value is identical to the default value or the computed value or the built in value. .SS "fetch_standard" .IX Subsection "fetch_standard" Returns the standard value as defined by the configuration model. The standard value can be either a preset value, a layered value, a computed value, a default value or a built-in default value. .SS "has_data" .IX Subsection "has_data" Return true if the value contains information different from default or upstream default value. .SS "fetch" .IX Subsection "fetch" Check and fetch value from leaf element. The method can have one parameter (the fetch mode) or several pairs: .IP "mode" 4 .IX Item "mode" Whether to fetch default, custom, etc value. See below for details .IP "check" 4 .IX Item "check" Whether to check if the value is valid or not before returning it. Default is 'yes'. Possible value are .RS 4 .IP "yes" 4 .IX Item "yes" Perform check and raise an exception for bad values .IP "skip" 4 .IX Item "skip" Perform check and return undef for bad values. A warning is issued when a bad value is skipped. Set \f(CW\*(C`check\*(C'\fR to \f(CW\*(C`no\*(C'\fR to avoid warnings. .IP "no" 4 .IX Item "no" Do not check and return values even if bad .RE .RS 4 .RE .IP "silent" 4 .IX Item "silent" When set to 1, warning are not displayed on \s-1STDOUT.\s0 User is expected to read warnings with warning_msg method. .PP According to the \f(CW\*(C`mode\*(C'\fR parameter, this method returns either: .IP "empty mode parameter (default)" 4 .IX Item "empty mode parameter (default)" Value entered by user or default value if the value is different from upstream_default or layered value. Typically this value is written in a configuration file. .IP "backend" 4 .IX Item "backend" Alias for default mode. .IP "custom" 4 .IX Item "custom" The value entered by the user (if different from built in, preset, computed or default value) .IP "user" 4 .IX Item "user" The value most useful to user: the value that is used by the application. .IP "preset" 4 .IX Item "preset" The value entered in preset mode .IP "standard" 4 .IX Item "standard" The preset or computed or default or built in value. .IP "default" 4 .IX Item "default" The default value (defined by the configuration model) .IP "layered" 4 .IX Item "layered" The value found in included files (treated in layered mode: values specified there are handled as upstream default values). E.g. like in multistrap config. .IP "upstream_default" 4 .IX Item "upstream_default" The upstream_default value. (defined by the configuration model) .IP "non_upstream_default" 4 .IX Item "non_upstream_default" The custom or preset or computed or default value. Returns undef if either of this value is identical to the upstream_default value. This feature is useful to reduce data to write in configuration file. .IP "allow_undef" 4 .IX Item "allow_undef" With this mode, \f(CW\*(C`fetch()\*(C'\fR behaves like in \f(CW\*(C`user\*(C'\fR mode, but returns \&\f(CW\*(C`undef\*(C'\fR for mandatory values. Normally, trying to fetch an undefined mandatory value leads to an exception. .SS "fetch_summary" .IX Subsection "fetch_summary" Returns a truncated value when the value is a string or uniline that is too long to be displayed. .SS "user_value" .IX Subsection "user_value" Returns the value entered by the user. Does not use the default or computed value. Returns undef unless a value was actually stored. .SS "fetch_preset" .IX Subsection "fetch_preset" Returns the value entered in preset mode. Does not use the default or computed value. Returns undef unless a value was actually stored in preset mode. .SS "clear_preset" .IX Subsection "clear_preset" Delete the preset value. (Even out of preset mode). Returns true if other data are still stored in the value (layered or user data). Returns false otherwise. .SS "fetch_layered" .IX Subsection "fetch_layered" Returns the value entered in layered mode. Does not use the default or computed value. Returns undef unless a value was actually stored in layered mode. .SS "clear_layered" .IX Subsection "clear_layered" Delete the layered value. (Even out of layered mode). Returns true if other data are still stored in the value (layered or user data). Returns false otherwise. .SS "get( path => ..., mode => ... , check => ... )" .IX Subsection "get( path => ..., mode => ... , check => ... )" Get a value from a directory like path. .SS "set( path , value )" .IX Subsection "set( path , value )" Set a value from a directory like path. .SH "Examples" .IX Header "Examples" .SS "Number with min and max values" .IX Subsection "Number with min and max values" .Vb 6 \& bounded_number => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqnumber\*(Aq, \& min => 1, \& max => 4, \& }, .Ve .SS "Mandatory value" .IX Subsection "Mandatory value" .Vb 5 \& mandatory_string => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& mandatory => 1, \& }, \& \& mandatory_boolean => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqboolean\*(Aq, \& mandatory => 1, \& }, .Ve .SS "Enum with help associated with each value" .IX Subsection "Enum with help associated with each value" Note that the help specification is optional. .PP .Vb 8 \& enum_with_help => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, \& choice => [qw/a b c/], \& help => { \& a => \*(Aqa help\*(Aq \& } \& }, .Ve .SS "Migrate old obsolete enum value" .IX Subsection "Migrate old obsolete enum value" Legacy values \f(CW\*(C`a1\*(C'\fR, \f(CW\*(C`c1\*(C'\fR and \f(CW\*(C`foo/.*\*(C'\fR are replaced with \f(CW\*(C`a\*(C'\fR, \f(CW\*(C`c\*(C'\fR and \f(CW\*(C`foo/\*(C'\fR. .PP .Vb 10 \& with_replace => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqenum\*(Aq, \& choice => [qw/a b c/], \& replace => { \& a1 => \*(Aqa\*(Aq, \& c1 => \*(Aqc\*(Aq, \& \*(Aqfoo/.*\*(Aq => \*(Aqfoo\*(Aq, \& }, \& }, .Ve .SS "Enforce value to match a regexp" .IX Subsection "Enforce value to match a regexp" An exception is triggered when the value does not match the \f(CW\*(C`match\*(C'\fR regular expression. .PP .Vb 5 \& match => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& match => \*(Aq^foo\ed{2}$\*(Aq, \& }, .Ve .SS "Enforce value to match a Parse::RecDescent grammar" .IX Subsection "Enforce value to match a Parse::RecDescent grammar" .Vb 9 \& match_with_parse_recdescent => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& grammar => q{ \& token (oper token)(s?) \& oper: \*(Aqand\*(Aq | \*(Aqor\*(Aq \& token: \*(AqApache\*(Aq | \*(AqCC\-BY\*(Aq | \*(AqPerl\*(Aq \& }, \& }, .Ve .SS "Issue a warning if a value matches a regexp" .IX Subsection "Issue a warning if a value matches a regexp" Issue a warning if the string contains upper case letters. Propose a fix that translate all capital letters to lower case. .PP .Vb 9 \& warn_if_capital => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& warn_if_match => { \& \*(Aq/A\-Z/\*(Aq => { \& fix => \*(Aq$_ = lc;\*(Aq \& } \& }, \& }, .Ve .PP A specific warning can be specified: .PP .Vb 10 \& warn_if_capital => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& warn_if_match => { \& \*(Aq/A\-Z/\*(Aq => { \& fix => \*(Aq$_ = lc;\*(Aq, \& mesg => \*(AqNO UPPER CASE PLEASE\*(Aq \& } \& }, \& }, .Ve .SS "Issue a warning if a value does \s-1NOT\s0 match a regexp" .IX Subsection "Issue a warning if a value does NOT match a regexp" .Vb 10 \& warn_unless => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& warn_unless_match => { \& foo => { \& msg => \*(Aq\*(Aq, \& fix => \*(Aq$_ = "foo".$_;\*(Aq \& } \& }, \& }, .Ve .SS "Always issue a warning" .IX Subsection "Always issue a warning" .Vb 5 \& always_warn => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq, \& warn => \*(AqAlways warn whenever used\*(Aq, \& }, .Ve .SS "Computed values" .IX Subsection "Computed values" See \*(L"Examples\*(R" in Config::Model::ValueComputer. .SH "Upgrade" .IX Header "Upgrade" Upgrade is a special case when the configuration of an application has changed. Some parameters can be removed and replaced by another one. To avoid trouble on the application user side, Config::Model offers a possibility to handle the migration of configuration data through a special declaration in the configuration model. .PP This declaration must: .IP "\(bu" 4 Declare the deprecated parameter with a \f(CW\*(C`status\*(C'\fR set to \f(CW\*(C`deprecated\*(C'\fR .IP "\(bu" 4 Declare the new parameter with the instructions to load the semantic content from the deprecated parameter. These instructions are declared in the \f(CW\*(C`migrate_from\*(C'\fR parameters (which is similar to the \f(CW\*(C`compute\*(C'\fR parameter) .PP Here an example where a \s-1URL\s0 parameter is changed to a set of 2 parameters (host and path): .PP .Vb 8 \& \*(Aqold_url\*(Aq => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aquniline\*(Aq, \& status => \*(Aqdeprecated\*(Aq, \& }, \& \*(Aqhost\*(Aq => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aquniline\*(Aq, \& \& # the formula must end with \*(Aq$1\*(Aq so the result of the capture is used \& # as the host value \& migrate_from => { \& formula => \*(Aq$old =~ m!http://([\ew\e.]+)!; $1 ;\*(Aq, \& variables => { \& old => \*(Aq\- old_url\*(Aq \& }, \& use_eval => 1, \& }, \& }, \& \*(Aqpath\*(Aq => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aquniline\*(Aq, \& migrate_from => { \& formula => \*(Aq$old =~ m!http://[\ew\e.]+(/.*)!; $1 ;\*(Aq, \& variables => { \& old => \*(Aq\- old_url\*(Aq \& }, \& use_eval => 1, \& }, \& }, .Ve .SH "EXCEPTION HANDLING" .IX Header "EXCEPTION HANDLING" When an error is encountered, this module may throw the following exceptions: .PP Config::Model::Exception::Model Config::Model::Exception::Formula Config::Model::Exception::WrongValue Config::Model::Exception::WarpError .PP See Config::Model::Exception for more details. .SH "AUTHOR" .IX Header "AUTHOR" Dominique Dumont, (ddumont at cpan dot org) .SH "SEE ALSO" .IX Header "SEE ALSO" Config::Model, Config::Model::Node, Config::Model::AnyId, Config::Model::Warper, Config::Model::Exception Config::Model::ValueComputer, .SH "AUTHOR" .IX Header "AUTHOR" Dominique Dumont .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is Copyright (c) 2005\-2022 by Dominique Dumont. .PP This is free software, licensed under: .PP .Vb 1 \& The GNU Lesser General Public License, Version 2.1, February 1999 .Ve