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 πŸ’…
  • default parameter β€” 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_default value is not written in the configuration files. Only the fetch_standard method 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 a has element 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 configuration Config::Model::Instance is 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 of boolean, 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 for boolean. it says how to write a boolean value. default is [0,1], which ngl is not the most readable vibe. you can do write_as as ['false','true'] or ['no','yes'] πŸ¦‹
  • compute β€” computes a value from a formula plus other values. by default a computed value cannot be set. see Config::Model::ValueComputer for 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 for integer, number)
  • max β€” specify the maximum value (optional, only for integer, number)
  • mandatory β€” set to 1 if the configuration value must be set by the configuration user (default: 0)
  • choice β€” array ref of the possible values of an enum. 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 with foo. only valid for string or uniline values.
  • 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 for string or uniline values. the fix instructions get evaluated when apply_fixes is called. $_ contains the value to fix. $_ is stored as the new value once the instructions finish. $self contains 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 for string or uniline values.
  • 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 like warn_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 the file sub (otherwise tests will break). that sub returns a Path::Tiny object you can use to do the checks. for instance:
warn_if => {
   warn_test => {
       code => 'not file($_)->exists',
       msg  => 'file $_ should exist'
   }
  • warn_unless β€” like warn_if, but it issues a warning when the given code returns 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 β€” like warn_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 a Parse::RecDescent grammar 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 for enum to 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 value foo is obsolete and replaced by foo_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 the replace parameter. here though, the replacement isn't coded in the model β€” it's specified by the configuration.
  • refer_to β€” specify a path to an id element used as a reference. see Value Reference for details.
  • computed_refer_to β€” specify a path to an id element 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 values 1 or 0, "yes" or "no", "true" or "false", and the empty string. the value you read back is always 1 or 0. no cap.
  • enum β€” enum choices must be specified by the choice parameter.
  • integer β€” enables positive or negative integers
  • number β€” the value can be a decimal number
  • uniline β€” 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 an enum where 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 subroutine failures.
  • 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, Europe and Japan in the example above) cannot be checked at start time against the warp master Value. 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_type to reference.
  • Specify the refer_to or computed_refer_to parameter. See the refer_to parameter 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:

  • min
  • max
  • mandatory
  • choice
  • convert
  • value_type
  • default
  • upstream_default
  • index_value
  • element_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:

  • value
  • quiet β€” 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 return undef for bad values. A warning is issued when a bad value is skipped. Set check to no to avoid those warnings.
    • no β€” do not check, and return values even if they're bad. Living dangerously, I see you. πŸ’…
  • silent β€” when set to 1, warnings are not displayed on STDOUT. You're expected to read the warnings yourself with the warning_msg method. 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_default or the layered value. Typically this value is the one written in a configuration file.
  • backend β€” alias for default mode.
  • 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 β€” the upstream_default value (defined by the configuration model).
  • non_upstream_default β€” the custom or preset or computed or default value. Returns undef if any of these values is identical to the upstream_default value. This feature is useful to reduce data to write in the configuration file. ✨
  • allow_undef β€” with this mode, fetch() behaves like in user mode, but returns undef for 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 status set to deprecated.
  • Declare the new parameter with the instructions to load the semantic content from the deprecated parameter. These instructions are declared in the migrate_from parameters (which is similar to the compute parameter).

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


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