Config...:Value(3pm)
π Config::Model::Value(3pm) π
User Contributed Perl Documentation
π NAME π
Config::Model::Value β Strongly typed configuration value
π« VERSION π«
version 2.166 β¨
π SYNOPSIS π
okay bestie, here's the whole vibe in code:
use Config::Model;
# define configuration tree object
my $model = Config::Model->new;
$model ->create_config_class (
name => "MyClass",
element => [
foo => {
type => 'leaf',
value_type => 'string',
description => 'foobar',
},
bar => '*foo',
country => {
type => 'leaf',
value_type => 'enum',
choice => [qw/France US/],
description => 'big countries',
}
]
) ;
my $inst = $model->instance(root_class_name => 'MyClass' );
my $root = $inst->config_root ;
# put data
$root->load( steps => 'foo=FOO country=US' );
print $root->report ;
# foo = FOO
# DESCRIPTION: foobar
#
# country = US
# DESCRIPTION: big countries
πΈ DESCRIPTION πΈ
This class is literally the blueprint for a configuration value with these properties, no cap:
- Strongly typed scalar β the value can either be an enumerated type, a boolean, a number, an integer, or a string. Pick your fighter π
defaultparameter β a value can have a default value specified during the construction. This default value is written in the target configuration file. (the"default"parameter)- upstream default parameter β this specifies a default value that is used by the application when no information is provided in the configuration file. This
upstream_defaultvalue is not written in the configuration files. Only thefetch_standardmethod returns the builtin value. This parameter was previously referred as the"built_in"value. This may be used for audit purpose. (the"upstream_default"parameter) - mandatory value β reading a mandatory value raises an exception if the value is not specified (i.e. is
"undef"or empty string) and has no default value. π - 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'US'and'A4'for country'France'. It's giving dynamic π - 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 ahaselement somewhere in the tree. See"Value Reference". - update from an external file β a value can be extracted from an external file. External file? More like external slay β¨
π Default values π
There are several kind of default values. They depend on where these values are defined (or found).
From the lowest default level to the "highest":
"upstream_default"β the value is known in the application, but is not written in the configuration file."layered"β the value is known by the application through another mean (e.g. an included configuration file), but is not written in the configuration file."default"β the value is known by the model, but not by the application. This value must be written in the configuration file."computed"β the value is computed from other configuration elements. This value must be written in the configuration file."preset"β 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 configurationConfig::Model::Instanceis in preset mode.
Then there is the value entered by the user. This overrides all kind of "default" value.
The fetch_standard function returns the "highest" level of default value, but does not return a custom value, i.e. a value entered by the user.
π Constructor π
Value object should not be created directly. Just don't π
Value model declaration β¨
okay so every leaf element has to be declared with these parameters. yes, all of these. it's a lot, but it's giving very thorough π
value_typeβ one ofboolean,enum,integer,number,uniline,string,file,dir. Mandatory. see "Value types" below bestie πdefaultβ specify the default value (optional)upstream_defaultβ specify a built-in default value (optional). like, a value the application already knows about that never needs to be written into the config file. iconic.write_asβ an array ref. reserved forboolean. it says how to write a boolean value. default is[0,1], which ngl is not the most readable vibe. you can dowrite_asas['false','true']or['no','yes']π¦computeβ computes a value from a formula plus other values. by default a computed value cannot be set. seeConfig::Model::ValueComputerfor computed value declaration.migrate_fromβ special little parameter for a smooth configuration upgrade. you use it to copy the value of a deprecated parameter over to its replacement. see "Upgrade" for details πconvert => [uc | lc ]β when it gets stored, the value is converted to uppercase (uc) or lowercase (lc).minβ specify the minimum value (optional, only forinteger,number)maxβ specify the maximum value (optional, only forinteger,number)mandatoryβ set to1if the configuration value must be set by the configuration user (default:0)choiceβ array ref of the possible values of anenum. example:
choice => [ qw/foo bar/]
matchβ a Perl regular expression. the value gets matched against the regex to assert its validity. example:match => '^foo'means the parameter value has to begin withfoo. only valid forstringorunilinevalues.warn_if_matchβ hash ref. the keys are Perl regular expressions. the value can specify a warning message (leave it empty or undefined for a default warning message) plus instructions to fix the value. a warning gets issued when the value matches the regex you passed. only valid forstringorunilinevalues. the fix instructions get evaluated whenapply_fixesis called.$_contains the value to fix.$_is stored as the new value once the instructions finish.$selfcontains the value object. use with care π«£
in the example below, any value matching 'foo' gets converted to uppercase:
warn_if_match => {
'foo' => {
fix => 'uc;',
msg => 'value $_ contains foo'
},
'BAR' => {
fix =>'lc;',
msg => 'value $_ contains BAR'
}
},
the tests run in alphabetical order. so in the example above, the BAR test happens before the foo test. lowkey important, ngl.
$_ gets substituted with the bad value when the message is generated. $std_value gets substituted with the standard value (i.e. the preset, computed or default value).
warn_unless_matchβ a hash ref just like the one above. a warning is issued when the value does not match the regex you passed. only valid forstringorunilinevalues.warnβ a string. issues a warning to the user with the string you specify, any time the value is set or read.warn_ifβ a bit likewarn_if_match, except the hash key isn't a regexp, it's a label to help users out. the hash ref contains some Perl code that gets evaluated to run the test. a warning is issued if that code returns true.
$_ contains the value to check. $self contains the Config::Model::Value object (use with care).
the example below warns if the value has a number in it:
warn_if => {
warn_test => {
code => 'defined $_ && /\d/;',
msg => 'value $_ should not have numbers',
fix => 's/\d//g;'
}
},
the hash key gets used in the warning message when msg isn't set:
warn_if => {
'should begin with foo' => {
code => 'defined && /^foo/'
}
}
any operation or check on a file must be done with thefilesub (otherwise tests will break). that sub returns aPath::Tinyobject you can use to do the checks. for instance:
warn_if => {
warn_test => {
code => 'not file($_)->exists',
msg => 'file $_ should exist'
}
warn_unlessβ likewarn_if, but it issues a warning when the givencodereturns false.
the example below warns unless the value points to a directory that actually exists:
warn_unless => {
'missing dir' => {
code => '-d',
fix => "system(mkdir $_);" }
}
assertβ likewarn_if, except the returned value triggers an error when the given code returns false:
assert => {
test_nb => {
code => 'defined $_ && /\d/;',
msg => 'should not have numbers',
fix => 's/\d//g;'
}
},
the hash key can also be used to generate the error message when the msg parameter isn't set.
grammarβ sets up aParse::RecDescentgrammar to do validation.
if the grammar doesn't start with a check rule (i.e. it doesn't start with check: ), the first line of the grammar gets modified to add a check rule, and that rule is set up so the entire value must match the grammar you passed.
i.e. the grammar:
token (oper token)(s?)
oper: 'and' | 'or'
token: 'Apache' | 'CC-BY' | 'Perl'
becomes:
check: token (oper token)(s?) /^\Z/ {$return = 1;}
oper: 'and' | 'or'
token: 'Apache' | 'CC-BY' | 'Perl'
the rule is called with the Value object and a string reference. so inside the actions you may need to define, you can call the value object as $arg[0], store the error message in "${$arg[1]}}" and store warnings in "${$arg[2]}}". π
replaceβ hash ref. used forenumto substitute one value with another. you have to use this parameter to let users upgrade a configuration that has obsolete values. for instance, if the valuefoois obsolete and replaced byfoo_better, you must declare:
replace => { foo => 'foo_better' }
the hash key can also be a regular expression for wider range replacement. the regexp must match the whole value:
replace => ( 'foo.*' => 'better_foo' }
in that case, a value gets replaced by better_foo when the /^foo.*$/ regexp matches. π₯
replace_followβ a path specifying a hash of value element in the configuration tree. the hash is used in a way similar to thereplaceparameter. here though, the replacement isn't coded in the model β it's specified by the configuration.refer_toβ specify a path to anidelement used as a reference. see Value Reference for details.computed_refer_toβ specify a path to anidelement used as a computed reference. see "Value Reference" for details.warpβ see the section below: "Warp: dynamic value configuration".helpβ you can give a detailed description of the possible values with a hash ref. example:
help => { oui => "French for 'yes'", non => "French for 'no'"}
the key of help is used as a regular expression to find the help text that applies to a value. these regexps are tried from the longest to the shortest, and they're matched from the beginning of the string. the key "." or ".*" are fallback, used last.
for instance:
help => {
'foobar' => 'help for values matching /^foobar/',
'foo' => 'help for values matching /^foo/ but not /^foobar/ (used above)',
'.' => 'help for all other values'
}
updateβ see "update" β¨
Value types π
this module can check a whole bunch of value types, get into it:
booleanβ accepts values1or0,"yes"or"no","true"or"false", and the empty string. the value you read back is always1or0. no cap.enumβ enum choices must be specified by thechoiceparameter.integerβ enables positive or negative integersnumberβ the value can be a decimal numberunilineβ a one line string. i.e. no"\n"up in it.stringβ actually, no check is performed with this type. it's giving chill π¦referenceβ like anenumwhere the possible values (aka choice) are defined by another location in the configuration tree. see "Value Reference".fileβ a file name or path. a warning is issued if the file doesn't exist (or is a directory).dirβ a directory name or path. a warning is issued if the directory doesn't exist (or is a plain file).
update π
this one specifies how the value can be updated from an external file. you have to specify the file type (ini, yaml, json or toml), the file path (absolute, or relative to wherever the program is run from), and the sub path to get the data. several files can be tried, bestie.
for instance, the value of the repository element below is loaded from package.json using the repository and url keys:
element => [
repository => {
type => 'leaf',
value_type => 'unline',
update => [
{
type => 'json',
file => "package.json",
subpath => "repository.url"
}
]
}
]
here's an example that tries 2 files:
update => [ {
type => 'json',
file => 'META.json',
subpath => 'resources.repository.url'
} , {
type => 'ini',
file => 'dist.ini',
subpath => 'MetaResources.repository\.url'
}]
note the \. β that's there so a sub path element can have an embedded dot in it. π
note that values get updated when the update_from_file method is called. this is the case when you run a cme udpate command (see App::Cme::Command::update for details).
β¨ Warp: dynamic value configuration β¨
Okay bestie, this is the iconic part. The Warp thing makes a Value object able to change its own properties (like its default value, or even its type) on the fly, based on the value of another Value object chilling somewhere else in the config tree. (If you want the full breakdown of how warping actually works under the hood, go read Config::Model::Warper, mmkay?)
So like, say you declare 2 Value elements like this:
$model ->create_config_class (
name => "TV_config_class",
element => [
country => {
type => 'leaf',
value_type => 'enum',
choice => [qw/US Europe Japan/]
} ,
tv_standard => { # this example is getting old...
type => 'leaf',
value_type => 'enum',
choice => [ qw/PAL NTSC SECAM/ ]
warp => {
follow => {
# this points to the warp master
c => '- country'
},
rules => [
{
when => '$c eq "US"',
apply => { default => 'NTSC' }
},
{
when => '$c eq "France"',
apply => { default => 'SECAM' }
},
{
when => '$c eq "Japan"',
apply => { default => 'NTSC' }
},
{
when => '$c eq "Europe"',
apply => { default => 'PAL' }
},
]
}
}
]
);
So if you set the country element to US, then tv_standard gets its default value set to NTSC by the warp mechanism. Magic. No cap. π
And it's not just defaults β warping also lets you dynamically swap out the possible values of an enum element:
state => {
type => 'leaf',
value_type => 'enum', # example is admittedly silly
warp => {
follow => {
c => '- country'
},
rules => [
{
when => '$c eq "US"',
apply => { choice => ['Kansas', 'Texas' ] }
},
{
when => '$c eq "Europe"',
apply => { choice => ['France', 'Spain' ] }
},
{
when => '$c eq "Japan"',
apply => { choice => ['Honshu', 'Hokkaido' ] }
}
]
}
}
πͺοΈ Cascaded warping πͺοΈ
Warping values can be cascaded: A can be warped by B, which can be warped by C. But ngl bestie, avoid this β it can make a model that is genuinely a nightmare to debug. Keep in mind that:
- Warp loops are not detected π and end up in
deep recursion subroutinefailures. - Avoid
"diamond"shaped warp dependencies β the results depend on the order the warp algorithm runs in, and that order can be unpredictable in this case. yikes - The keys declared in the warp rules (
US,EuropeandJapanin the example above) cannot be checked at start time against the warp masterValue. So a wrong warp rule key gets silently ignored during start up and then fails at run time. π
π Value Reference π
So you wanna set up an enumerated value where the possible choices depend on the key of a Config::Model::AnyId object? Then you gotta:
- Set
value_typetoreference. - Specify the
refer_toorcomputed_refer_toparameter. See therefer_toparameter for more.
When you do that, an IdElementReference object gets created to handle the relation between this value object and the referred Id. See Config::Model::IdElementReference for all the details. β¨
π Introspection methods π
These methods all return the current value of the value object's parameter β as declared in the model, unless the parameter got warped, in which case you get the warped one:
minmaxmandatorychoiceconvertvalue_typedefaultupstream_defaultindex_valueelement_name
π·οΈ name
Returns the object name.
π get_type
Returns leaf.
βοΈ can_store
Returns true if the value object can be assigned to. Returns 0 for a read-only value (i.e. a computed value with no override allowed).
π get_choice
Query the legal values (only for enum types, bestie). Returns an array (which might be empty π«).
π¬ get_help
With a parameter, it returns the help string that applies to the passed value β or undef.
Without a parameter, it returns a hash ref containing all the help strings.
βΉοΈ get_info
Returns a list of info related to the value, like value type and default value. You'd use this to hand the user some debug info.
For instance, "$val-"get-info> may return:
[ 'type: string', 'mandatory: yes' ]
π¨ error_msg
Returns the error messages of this object (if there are any).
β οΈ warning_msg
Returns warnings concerning this value. Returns a list in list context and a string in scalar context. (iykyk π )
β check_value
Parameters: ( value )
Checks the consistency of the value.
check_value also accepts named parameters:
valuequietβ when non null, the 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 ...
In scalar context, it returns 0 or 1.
In array context, it returns an empty array when no error was found. If there were errors, it returns an array of error strings that should be shown to the user.
π©Ή has_fixes
Returns the number of fixes that can be applied to the current value.
π οΈ apply_fixes
Applies the fixes to suppress the current warnings.
π check
Parameters: ( [ value => foo ] )
Works like check_value.
It also displays warnings on STDOUT unless the silent parameter is set to 1. In that case, the user is expected to retrieve them with warning_msg.
Without a value argument, this method checks the value that is currently stored.
π is_bad_mode
Accepts a mode parameter. This function checks if the mode is accepted by the fetch method. Returns an error message if it's not. For instance:
if (my $err = $val->is_bad_mode('foo')) {
croak "my_function: $err";
}
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) π¦
β¨ Information management β¨
store
Parameters: ( $value ) or (value => ..., check => yes|no|skip , silent => 0|1 )
Stores the value right there in the leaf element, bestie. Slips it in. Puts it away. πΎ
The check parameter lets you skip the validation check β default is 'yes', as it should be, because we do check our work in this house. And silent can be used to suppress warnings, for when you just cannot with the noise today.
Heads up: the optional callback is now deprecated. It's giving legacy. Do not use it. π
clear
Clears the stored value. Ngl this one's dramatic β after clearing, a further read hands you back the default value (which can be a computed value or a migrated value), or undef. Whichever it is, it's not your value anymore. π
Parameters: ( check => yes|no|skip , silent => 0|1 )
The check parameter can be used to skip the validation check (default is 'yes') for mandatory values. And silent can be used to suppress warnings, again, because sometimes you just need peace.
load_data
Parameters: ( $value )
Called with the same parameters as the store method. It loads scalar data β and it only forwards the data on to store after checking that the value you passed is not a reference. Scalar data only, babe. No sneaky refs. β¨
fetch_custom
Returns the stored value if that value is different from a standard setting or a built-in setting. In other words: it returns undef if the stored value is identical to the default value, or the computed value, or the built-in value. So if it's the same, it's likeβ¦ nothing to see here. π«₯
fetch_standard
Returns the standard value exactly as defined by the configuration model. That standard value can be a preset value, a layered value, a computed value, a default value, or a built-in default value. So many flavours, all of them valid. π
has_data
Returns true if the value contains information different from the default or upstream default value. Basically: "is there anything actual in here?" π΅οΈ
fetch
Check and fetch a value from the leaf element. This method can take one parameter (the fetch mode) or several pairs:
modeβ whether to fetch default, custom, etc. value. Details below, keep scrolling πcheckβ whether to check that the value is valid before returning it. Default is'yes'. Possible values are:yesβ perform the check and raise an exception for bad values πskipβ perform the check and returnundeffor bad values. A warning is issued when a bad value is skipped. Setchecktonoto avoid those warnings.noβ do not check, and return values even if they're bad. Living dangerously, I see you. π
silentβ when set to1, warnings are not displayed on STDOUT. You're expected to read the warnings yourself with thewarning_msgmethod. The receipts are still there, bestie, they're just not being shoved in your face.
Depending on the mode parameter, this method returns either:
- empty mode parameter (default) β the value entered by the user, or the default value if the value is different from
upstream_defaultor the layered value. Typically this value is the one written in a configuration file. backendβ alias fordefaultmode.customβ the value entered by the user (if it's different from the built-in, preset, computed or default value).userβ the value most useful to the user: the value that's actually used by the application. Main character value, honestly. πpresetβ the value entered in preset mode.standardβ the preset or computed or default or built-in value.defaultβ the default value (defined by the configuration model).layeredβ the value found in included files (treated in layered mode: values specified there are handled as upstream default values).upstream_defaultβ theupstream_defaultvalue (defined by the configuration model).non_upstream_defaultβ the custom or preset or computed or default value. Returnsundefif any of these values is identical to theupstream_defaultvalue. This feature is useful to reduce data to write in the configuration file. β¨allow_undefβ with this mode,fetch()behaves like inusermode, but returnsundeffor mandatory values. Normally, trying to fetch an undefined mandatory value leads to an exception. So this is your β¨get out of jail freeβ¨ card.
fetch_summary
Returns a truncated value when the value is a string or uniline that is too long to be displayed. It's the "β¦and the rest" of values. π
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. No stored value, no vibes.
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.
clear_preset
Deletes the preset value. (Even outside of preset mode.) Returns true if other data are still stored in the value (layered or user data). Returns false otherwise. π§Ή
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.
clear_layered
Deletes the layered value. (Even outside of layered mode.) Returns true if other data are still stored in the value (layered or user data). Returns false otherwise.
get( path => ..., mode => ... , check => ... )
Gets a value from a directory-like path. Follow the path, grab the value. πΊοΈ
set( path , value )
Sets a value from a directory-like path.
update_from_file
Triggers an update from the files specified in the update configuration parameter. This method is intended to be called by update in Config::Model::Instance. It's an inside job, iykyk. π
π EXAMPLES π
Number with min and max values
bounded_number => {
type => 'leaf',
value_type => 'number',
min => 1,
max => 4,
},
Mandatory value
mandatory_string => {
type => 'leaf',
value_type => 'string',
mandatory => 1,
},
mandatory_boolean => {
type => 'leaf',
value_type => 'boolean',
mandatory => 1,
},
Enum with help associated with each value
Note that the help specification is optional. You can be mysterious if you want. π
enum_with_help => {
type => 'leaf',
value_type => 'enum',
choice => [qw/a b c/],
help => {
a => 'a help'
}
},
Migrate old obsolete enum value
Legacy values a1, c1 and foo/.* get replaced with a, c and foo/. Out with the old, in with the glow-up. π¦
with_replace => {
type => 'leaf',
value_type => 'enum',
choice => [qw/a b c/],
replace => {
a1 => 'a',
c1 => 'c',
'foo/.*' => 'foo',
},
},
Enforce value to match a regexp
An exception is triggered when the value does not match the match regular expression. The regexp said what it said. π₯
match => {
type => 'leaf',
value_type => 'string',
match => '^foo\d{2}$',
},
Enforce value to match a Parse::RecDescent grammar
match_with_parse_recdescent => {
type => 'leaf',
value_type => 'string',
grammar => q{
token (oper token)(s?)
oper: 'and' | 'or'
token: 'Apache' | 'CC-BY' | 'Perl'
},
},
Issue a warning if a value matches a regexp
Issues a warning if the string contains upper case letters. It also proposes a fix that translates all capital letters to lower case. So thoughtful of it. π
warn_if_capital => {
type => 'leaf',
value_type => 'string',
warn_if_match => {
'/A-Z/' => {
fix => '$_ = lc;'
}
},
},
And a specific warning message can be specified:
warn_if_capital => {
type => 'leaf',
value_type => 'string',
warn_if_match => {
'/A-Z/' => {
fix => '$_ = lc;',
msg => 'NO UPPER CASE PLEASE'
}
},
},
Issue a warning if a value does NOT match a regexp
warn_unless => {
type => 'leaf',
value_type => 'string',
warn_unless_match => {
foo => {
msg => '',
fix => '$_ = "foo".$_;'
}
},
},
Always issue a warning
always_warn => {
type => 'leaf',
value_type => 'string',
warn => 'Always warn whenever used',
},
Computed values
See "Examples" in Config::Model::ValueComputer. Go check it out, it's a whole thing. β¨
Upgrade
Upgrade is a special case for 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 way to handle the migration of configuration data through a special declaration in the configuration model. It's the glow-up arc of your config. π¦
This declaration must:
- Declare the deprecated parameter with a
statusset todeprecated. - Declare the new parameter with the instructions to load the semantic content from the deprecated parameter. These instructions are declared in the
migrate_fromparameters (which is similar to thecomputeparameter).
Here's an example where a URL parameter is changed to a set of 2 parameters (host and path):
'old_url' => {
type => 'leaf',
value_type => 'uniline',
status => 'deprecated',
},
'host' => {
type => 'leaf',
value_type => 'uniline',
# the formula must end with '$1' so the result of the capture is used
# as the host value
migrate_from => {
formula => '$old =~ m!http://([\w\.]+)!; $1 ;',
variables => {
old => '- old_url'
},
use_eval => 1,
},
},
'path' => {
type => 'leaf',
value_type => 'uniline',
migrate_from => {
formula => '$old =~ m!http://[\w\.]+(/.*)!; $1 ;',
variables => {
old => '- old_url'
},
use_eval => 1,
},
},
π EXCEPTION HANDLING π
When an error is encountered, this module may throw the following exceptions:
Config::Model::Exception::Model Config::Model::Exception::Formula Config::Model::Exception::WrongValue Config::Model::Exception::WarpError
See Config::Model::Exception for more details. The drama lives there. π
π AUTHOR π
Dominique Dumont, (ddumont at cpan dot org)
π«Ά SEE ALSO π«Ά
Config::Model, Config::Model::Node, Config::Model::AnyId, Config::Model::Warper, Config::Model::Exception Config::Model::ValueComputer,
π AUTHOR π
Dominique Dumont
β COPYRIGHT AND LICENSE β
This software is Copyright (c) 2005-2022 by Dominique Dumont.
This is free software, licensed under:
The GNU Lesser General Public License, Version 2.1, February 1999
And that's the whole page, bestie β no cap, we got every single flag, mode and footnote in there. π
This one's from perl v5.42.3, dated 2026-07-23 β so yes, it's fresh, and it's the Config::Model::Value(3pm) manual page. Now go forth and configure your little heart out. πβ¨π¦
π¦ where this page comes from
- ubuntu stonking: libconfig-model-perl 2.166-1 Β· LGPL-2.1-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms