1Config::Model::ValueComUpsuetrerC(o3n)tributed Perl DocuCmoennftiagt:i:oMnodel::ValueComputer(3)
2
3
4

NAME

6       Config::Model::ValueComputer - Provides configuration value computation
7

VERSION

9       version 2.152
10

SYNOPSIS

12        use Config::Model;
13
14        # define configuration tree object
15        my $model = Config::Model->new;
16        $model ->create_config_class (
17           name => "MyClass",
18
19           element => [
20              [qw/av bv/] => {
21                  type => 'leaf',
22                  value_type => 'integer',
23              },
24              compute_int => {
25                      type => 'leaf',
26                      value_type => 'integer',
27                      compute    => {
28                          formula   => '$a + $b',
29                          variables => { a => '- av', b => '- bv'}
30                      },
31              },
32           ],
33        );
34
35        my $inst = $model->instance(root_class_name => 'MyClass' );
36
37        my $root = $inst->config_root ;
38
39        # put data
40        $root->load( steps => 'av=33 bv=9' );
41
42        print "Computed value is ",$root->grab_value('compute_int'),"\n";
43        # Computed value is 42
44

DESCRIPTION

46       This class provides a way to compute a configuration value. This
47       computation uses a formula and some other configuration values from the
48       configuration tree.
49
50       The computed value can be overridden, in other words, the computed
51       value can be used as a default value.
52

Computed value declaration

54       A computed value must be declared in a 'leaf' element. The leaf element
55       must have a "compute" argument pointing to a hash ref.
56
57       This array ref contains:
58
59       •   A string formula that use variables and replace function.
60
61       •   A set of variable and their relative location in the tree (using
62           the notation explained in grab method
63
64       •   An optional set of replace rules.
65
66       •   An optional parameter to force a Perl eval of a string.
67
68       Note: A variable must point to a valid location in the configuration
69       tree. Even when "&index()" or $replace{} is used. After substitution of
70       these functions, the string is used as a path (See grab) starting from
71       the computed value. Hence the path must begin with "!" to go back to
72       root node, or "-" to go up a level.
73
74   Compute formula
75       The first element of the "compute" array ref must be a string that
76       contains the computation algorithm (i.e. a formula for arithmetic
77       computation for integer values or a string template for string values).
78
79       This string or formula should contain variables (like $foo or $bar).
80       Note that these variables are not interpolated by Perl.
81
82       For instance:
83
84         'My cat has $nb legs'
85         '$m * $c**2'
86
87       This string or formula may also contain:
88
89       •   The index value of the current object : &index or "&index()".
90
91       •   The index value of a parent object: "&index(-)". Ancestor index
92           value can be retrieved with "&index(-2)" or "&index(-3)" or
93           "&index(- -)" or "&index(- - -)"
94
95       •   The element name of the current object: &element or "&element()".
96
97       •   The element name of a parent object: "&element(-)". Likewise,
98           ancestor element name can be retrieved with "&element(-2)" or
99           "&element(-3)".
100
101       •   The full location (path) of the current object: &location or
102           "&location()".
103
104       For instance, you could have this template string:
105
106          'my element is &element, my index is &index' .
107           'upper element is &element(-), upper index is &index(-)',
108
109       If you need to perform more complex operations than substitution, like
110       extraction with regular expressions, you can force an eval done by Perl
111       with "use_eval => 1". In this case, the result of the eval is used as
112       the computed value.
113
114       For instance:
115
116         # extract host from url
117         compute => {
118             formula => '$old =~ m!http://[\w\.]+(?::\d+)?(/.*)!; $1 ;',
119             variables => { old => '- url' } ,
120                 use_eval => 1 ,
121         },
122
123         # capitalize
124         compute => {
125             formula => 'uc($old)',
126                 variables => { old => '- small_caps' } ,
127                 use_eval => 1
128         }
129
130   Compute variables
131       Compute variables are a set of "key => value" pairs that define the
132       variables used in the specified formula. The key is a variable name
133       used in the string that represents the formula. The value is a string
134       that is used to get the correct Value object.
135
136       In this numeric example, "result" default value is "av + bv":
137
138        element => [
139           av => {
140               type => 'leaf',
141               value_type => 'integer'
142           },
143           bv => {
144               type => 'leaf',
145               value_type => 'integer'
146           },
147           result => {
148               type => 'leaf',
149               value_type => 'integer',
150               compute => {
151                   formula => '$a + $b' ,
152                   variables => { a => '- av', b => '- bv' },
153               }
154           }
155        ]
156
157       In this string example, the default value of the "Comp" element is
158       actually a string made of ""macro is "" and the value of the ""macro""
159       element of the object located 2 nodes above:
160
161        comp => {
162           type => 'leaf',
163           value_type => 'string',
164           compute => {
165               formula => '"macro is $m"' ,
166               variables => { m => '- - macro' }
167           }
168        }
169
170   Compute replace
171       Sometime, using the value of a tree leaf is not enough and you need to
172       substitute a replacement for any value you can get. This replacement
173       can be done using a hash like notation within the formula using the
174       %replace hash.
175
176       For instance, if you want to display a summary of a config, you can do
177       :
178
179        compute_with_replace => {
180            formula => '$replace{$who} is the $replace{$what} of $replace{$country}',
181            variables => {
182                who   => '! who' ,
183                what  => '! what' ,
184                country => '- country',
185            },
186            replace => {
187                chief => 'president',
188                America => 'USA'
189            }
190        }
191
192   Complex formula
193       &index, &element, and replace can be combined. But the argument of
194       &element or &index can only be a value object specification (I.e.
195       something like '"- - foo"'), it cannot be a value replacement of
196       another &element or &index.
197
198       I.e. "&element($foo)" is ok, but "&element(&index($foo))" is not
199       allowed.
200
201   computed variable
202       Compute variables can themselves be computed :
203
204        compute => {
205           formula => 'get_element is $replace{$s}, indirect value is \'$v\'',
206           variables => {
207               s => '! $where',
208               where => '! where_is_element',
209               v => '! $replace{$s}',
210           }
211           replace => {
212               m_value_element => 'm_value',
213               compute_element => 'compute'
214           }
215        }
216
217       Be sure not to specify a loop when doing recursive computation.
218
219       The function &index &element and &location are also allowed.
220
221   compute override
222       In some case, a computed value must be interpreted as a default value
223       and the user must be able to override this computed default value.  In
224       this case, you must use "allow_override => 1" with the compute
225       parameter:
226
227        computed_value_with_override => {
228           type => 'leaf',
229           value_type => 'string',
230           compute => {
231               formula => '"macro is $m"' ,
232               variables => { m => '- - macro' } ,
233               allow_override => 1,
234           }
235        }
236
237       This computed default value is written to the configuration file.
238
239       This default value may be already known by the application so the
240       computed value should not be written to the configuration file. The
241       computed value is interesting because it cab be shown to the user. In
242       this case, use the "use_as_upstream_default" parameter:
243
244        compute_known_upstream => {
245           type => 'leaf',
246           value_type => 'string',
247           compute => {
248               formula => '"macro is $m"' ,
249               variables => { m => '- - macro' } ,
250               use_as_upstream_default => 1,
251           }
252        }
253
254       "use_as_upstream_default" implies "allow_override".
255
256   Undefined variables
257       You may need to compute value where one of the variables (i.e. other
258       configuration parameter) is undefined. By default, any formula yields
259       an undefined value if one variable is undefined.
260
261       You may change this behavior with "undef_is" parameter. With this
262       parameter, you can specify a "fallback" value that is used in your
263       formula instead of an undefined variable.
264
265       The most useful fallback values are:
266
267        undef_is => "''", # for string values
268        undef_is => 0   , # for integers, boolean values
269
270       Example:
271
272        Source => {
273           type => 'leaf',
274           value_type   => 'string',
275           mandatory    => 1,
276           migrate_from => {
277               use_eval  => 1,
278               formula   => '$old || $older ;',
279               undef_is => "''",
280               variables => {
281                   older => '- Original-Source-Location',
282                   old   => '- Upstream-Source'
283               }
284           },
285        },
286        [qw/Upstream-Source Original-Source-Location/] => {
287           value_type => 'string',
288           status     => 'deprecated',
289           type       => 'leaf'
290        }
291

Examples

293   String substitution
294        [qw/sav sbv/] => {
295            type       => 'leaf',
296            value_type => 'string',
297          },
298        compute_string => {
299            type       => 'leaf',
300            value_type => 'string',
301            compute    => {
302                formula   => 'meet $a and $b',
303                variables => { '- sav', b => '- sbv' }
304            },
305        },
306
307   Computation with on-the-fly replacement
308        compute_with_replace => {
309            type       => 'leaf',
310            value_type => 'string',
311            compute    => {
312                formula =>
313                  '$replace{$who} is the $replace{$what} of $replace{$country}',
314                variables => {
315                    who     => '! who',
316                    what    => '! what',
317                    country => '- country',
318                },
319                replace => {
320                    chief   => 'president',
321                    America => 'USA'
322                },
323            },
324          },
325
326   Extract data from a value using a Perl regexp
327       Extract the host name from an URL:
328
329        url => {
330            type       => 'leaf',
331            value_type => 'uniline'
332        },
333        extract_host_from_url => {
334            type       => 'leaf',
335            value_type => 'uniline',
336            compute    => {
337                formula   => '$old =~ m!http://([\w\.]+)!; $1 ;',
338                variables => { old => '- url' },
339                use_eval  => 1,
340            },
341        },
342
343   copy hash example
344       Copying a hash may not be useful, but the using "&index()" in a
345       variable can be. Here's an example where the hashes contain leaves.
346
347       The model is set up so that the content of "copy_from" is copied into
348       "copy_to" hash:
349
350               copy_from => {
351                   'type' => 'hash',
352                   'index_type' => 'string',
353                   'cargo' => {
354                       'config_class_name' => 'From',
355                       'type' => 'node'
356                   },
357               },
358               copy_to => {
359                   'type' => 'hash',
360                   'index_type' => 'string',
361                   'cargo' => {
362                       'type' => 'leaf',
363                       'value_type' => 'uniline',
364                       'compute' => {
365                           'formula' => '$copied',
366                           'variables' => {
367                               'copied' => '- copy_from:&index()'
368                           }
369                       },
370                   },
371               },
372
373       Hash copy is also possible when the hash contains node. Here's an
374       example where the data to be copied is stored within a node. The main
375       class has 2 hash elements:
376
377               copy_from => {
378                   'type' => 'hash',
379                   'index_type' => 'string',
380                   'cargo' => {
381                       'config_class_name' => 'From',
382                       'type' => 'node'
383                   },
384               },
385               copy_to => {
386                   'type' => 'hash',
387                   'index_type' => 'string',
388                   'cargo' => {
389                       'config_class_name' => 'To',
390                       'type' => 'node'
391                   },
392               },
393
394       The Class to copy from is quite short:
395
396           'name' => 'From',
397           'element' => [
398               name =>  {
399                   'type' => 'leaf',
400                   'value_type' => 'uniline',
401               }
402           ]
403
404       Here the class to copy to:
405
406           'name' => 'To',
407           'element' => [
408               name =>  {
409                   'type' => 'leaf',
410                   'value_type' => 'uniline',
411                   'compute' => {
412                       'formula' => '$copied',
413                       'variables' => {
414                           'copied' => '! copy_from:&index(-) name'
415                       }
416                   },
417               }
418           ]
419

AUTHOR

421       Dominique Dumont, (ddumont at cpan dot org)
422

SEE ALSO

424       Config::Model, Config::Model::Instance, Config::Model::Value
425

AUTHOR

427       Dominique Dumont
428
430       This software is Copyright (c) 2005-2022 by Dominique Dumont.
431
432       This is free software, licensed under:
433
434         The GNU Lesser General Public License, Version 2.1, February 1999
435
436
437
438perl v5.36.0                      2022-08-10   Config::Model::ValueComputer(3)
Impressum