Config::Model::Value(3pm) | User Contributed Perl Documentation | Config::Model::Value(3pm) |
Config::Model::Value - Strongly typed configuration value
version 2.152
use Config::Model; # define configuration tree object my $model = Config::Model->new; $model ->create_config_class ( name => "MyClass", element => [ [qw/foo bar/] => { type => 'leaf', value_type => 'string', description => 'foobar', } , 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
This class provides a way to specify configuration value with the following properties:
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":
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.
Value object should not be created directly.
A leaf element must be declared with the following parameters:
choice => [ qw/foo bar/]
In the example below, any value matching 'foo' is converted in uppercase:
warn_if_match => { 'foo' => { fix => 'uc;', msg => 'value $_ contains foo' }, 'BAR' => { fix =>'lc;', msg => 'value $_ contains BAR' } },
The tests are done in alphabetical order. In the example above, "BAR" test is done before "foo" test.
$_ is substituted with the bad value when the message is generated. $std_value is substituted with the standard value (i.e the preset, computed or default value).
$_ contains the value to check. $self contains the "Config::Model::Value" object (use with care).
The example below warns if value contains a number:
warn_if => { warn_test => { code => 'defined $_ && /\d/;', msg => 'value $_ should not have numbers', fix => 's/\d//g;' } },
Hash key is used in warning message when "msg" is not set:
warn_if => { 'should begin with foo' => { code => 'defined && /^foo/' } }
Any operation or check on file must be done with "file" sub (otherwise tests will break). This sub returns a Path::Tiny object that can be used to perform checks. For instance:
warn_if => { warn_test => { code => 'not file($_)->exists', msg => 'file $_ should exist' }
The example below warns unless the value points to an existing directory:
warn_unless => { 'missing dir' => { code => '-d', fix => "system(mkdir $_);" } }
assert => { test_nb => { code => 'defined $_ && /\d/;', msg => 'should not have numbers', fix => 's/\d//g;' } },
hash key can also be used to generate error message when "msg" parameter is not set.
If the grammar does not start with a "check" rule (i.e does not start with "check: "), the first line of the grammar is modified to add "check" rule and this rules is set up so the entire value must match the passed grammar.
I.e. the grammar:
token (oper token)(s?) oper: 'and' | 'or' token: 'Apache' | 'CC-BY' | 'Perl'
is changed to
check: token (oper token)(s?) /^\Z/ {$return = 1;} oper: 'and' | 'or' token: 'Apache' | 'CC-BY' | 'Perl'
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 $arg[0], store error message in "${$arg[1]}}" and store warnings in "${$arg[2]}}".
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 this case, a value is replaced by "better_foo" when the "/^foo.*$/" regexp matches.
help => { oui => "French for 'yes'", non => "French for 'no'"}
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 ""."" 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' }
This modules can check several value types:
The Warp functionality enable a "Value" object to change its properties (i.e. default value or its type) dynamically according to the value of another "Value" object locate elsewhere in the configuration tree. (See Config::Model::Warper for an explanation on warp mechanism).
For instance if you declare 2 "Value" element this way:
$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 => { '$c eq "US"' => { default => 'NTSC' }, '$c eq "France"' => { default => 'SECAM' }, '$c eq "Japan"' => { default => 'NTSC' }, '$c eq "Europe"' => { default => 'PAL' }, } } } , ] );
Setting "country" element to "US" means that "tv_standard" has a default value set to "NTSC" by the warp mechanism.
Likewise, the warp mechanism enables you to dynamically change the possible values of an enum element:
state => { type => 'leaf', value_type => 'enum', # example is admittedly silly warp => { follow => { c => '- country' }, rules => { '$c eq "US"' => { choice => ['Kansas', 'Texas' ] }, '$c eq "Europe"' => { choice => ['France', 'Spain' ] }, '$c eq "Japan"' => { choice => ['Honshu', 'Hokkaido' ] } } } }
Warping value can be cascaded: "A" can be warped by "B" which can be warped by "C". But this feature should be avoided since it can lead to a model very hard to debug. Bear in mind that:
To set up an enumerated value where the possible choice depends on the key of a Config::Model::AnyId object, you must:
In this case, a "IdElementReference" object is created to handle the relation between this value object and the referred Id. See Config::Model::IdElementReference for details.
The following methods returns the current value of the parameter of the value object (as declared in the model unless they were warped):
Returns the object name.
Returns "leaf".
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).
Query legal values (only for enum types). Return an array (possibly empty).
With a parameter, returns the help string applicable to the passed value or undef.
Without parameter returns a hash ref that contains all the help strings.
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.
For instance, "$val-"get-info> may return:
[ 'type: string', 'mandatory: yes' ]
Returns the error messages of this object (if any)
Returns warning concerning this value. Returns a list in list context and a string in scalar context.
Parameters: "( value )"
Check the consistency of the value.
"check_value" also accepts named parameters:
In scalar context, return 0 or 1.
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.
Returns the number of fixes that can be applied to the current value.
Applies the fixes to suppress the current warnings.
Parameters: "( [ value => foo ] )"
Like "check_value".
Also displays warnings on STDOUT unless "silent" parameter is set to 1. In this case,user is expected to retrieve them with "warning_msg".
Without "value" argument, this method checks the value currently stored.
Accept a mode parameter. This function checks if the mode is accepted by "fetch" method. Returns an error message if 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)
Parameters: "( $value )" or "value => ..., check => yes|no|skip ), silent => 0|1"
Store value in leaf element. "check" parameter can be used to skip validation check (default is 'yes'). "silent" can be used to suppress warnings.
Optional "callback" is now deprecated.
Clear the stored value. Further read returns the default value (or computed or migrated value).
Parameters: "( $value )"
Called with the same parameters are "store" method.
Load scalar data. Data is forwarded to "store" after checking that the passed value is not a reference.
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.
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.
Return true if the value contains information different from default or upstream default value.
Check and fetch value from leaf element. The method can have one parameter (the fetch mode) or several pairs:
According to the "mode" parameter, this method returns either:
Returns a truncated value when the value is a string or uniline that is too long to be displayed.
Returns the value entered by the user. Does not use the default or computed value. Returns undef unless a value was actually stored.
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.
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.
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.
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.
Get a value from a directory like path.
Set a value from a directory like path.
bounded_number => { type => 'leaf', value_type => 'number', min => 1, max => 4, },
mandatory_string => { type => 'leaf', value_type => 'string', mandatory => 1, }, mandatory_boolean => { type => 'leaf', value_type => 'boolean', mandatory => 1, },
Note that the help specification is optional.
enum_with_help => { type => 'leaf', value_type => 'enum', choice => [qw/a b c/], help => { a => 'a help' } },
Legacy values "a1", "c1" and "foo/.*" are replaced with "a", "c" and "foo/".
with_replace => { type => 'leaf', value_type => 'enum', choice => [qw/a b c/], replace => { a1 => 'a', c1 => 'c', 'foo/.*' => 'foo', }, },
An exception is triggered when the value does not match the "match" regular expression.
match => { type => 'leaf', value_type => 'string', match => '^foo\d{2}$', },
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 the string contains upper case letters. Propose a fix that translate all capital letters to lower case.
warn_if_capital => { type => 'leaf', value_type => 'string', warn_if_match => { '/A-Z/' => { fix => '$_ = lc;' } }, },
A specific warning can be specified:
warn_if_capital => { type => 'leaf', value_type => 'string', warn_if_match => { '/A-Z/' => { fix => '$_ = lc;', mesg => 'NO UPPER CASE PLEASE' } }, },
warn_unless => { type => 'leaf', value_type => 'string', warn_unless_match => { foo => { msg => '', fix => '$_ = "foo".$_;' } }, },
always_warn => { type => 'leaf', value_type => 'string', warn => 'Always warn whenever used', },
See "Examples" in Config::Model::ValueComputer.
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.
This declaration must:
Here 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, }, },
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.
Dominique Dumont, (ddumont at cpan dot org)
Config::Model, Config::Model::Node, Config::Model::AnyId, Config::Model::Warper, Config::Model::Exception Config::Model::ValueComputer,
Dominique Dumont
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
2022-07-28 | perl v5.34.0 |