1Config::Model::ValueComUpsuetrerC(o3nptmr)ibuted Perl DoCcounmfeingt:a:tMioodnel::ValueComputer(3pm)
2
3
4

NAME

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

VERSION

9       version 2.153
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 value
92           can be retrieved with &index(-2) or &index(-3) or "&index(- -)" or
93           "&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 allowed.
199
200   computed variable
201       Compute variables can themselves be computed :
202
203        compute => {
204           formula => 'get_element is $replace{$s}, indirect value is \'$v\'',
205           variables => {
206               s => '! $where',
207               where => '! where_is_element',
208               v => '! $replace{$s}',
209           }
210           replace => {
211               m_value_element => 'm_value',
212               compute_element => 'compute'
213           }
214        }
215
216       Be sure not to specify a loop when doing recursive computation.
217
218       The function &index &element and &location are also allowed.
219
220   compute override
221       In some case, a computed value must be interpreted as a default value
222       and the user must be able to override this computed default value.  In
223       this case, you must use "allow_override => 1" with the compute
224       parameter:
225
226        computed_value_with_override => {
227           type => 'leaf',
228           value_type => 'string',
229           compute => {
230               formula => '"macro is $m"' ,
231               variables => { m => '- - macro' } ,
232               allow_override => 1,
233           }
234        }
235
236       This computed default value is written to the configuration file.
237
238       This default value may be already known by the application so the
239       computed value should not be written to the configuration file. The
240       computed value is interesting because it cab be shown to the user. In
241       this case, use the "use_as_upstream_default" parameter:
242
243        compute_known_upstream => {
244           type => 'leaf',
245           value_type => 'string',
246           compute => {
247               formula => '"macro is $m"' ,
248               variables => { m => '- - macro' } ,
249               use_as_upstream_default => 1,
250           }
251        }
252
253       "use_as_upstream_default" implies "allow_override".
254
255   Undefined variables
256       You may need to compute value where one of the variables (i.e. other
257       configuration parameter) is undefined. By default, any formula yields
258       an undefined value if one variable is undefined.
259
260       You may change this behavior with "undef_is" parameter. With this
261       parameter, you can specify a "fallback" value that is used in your
262       formula instead of an undefined variable.
263
264       The most useful fallback values are:
265
266        undef_is => "''", # for string values
267        undef_is => 0   , # for integers, boolean values
268
269       Example:
270
271        Source => {
272           type => 'leaf',
273           value_type   => 'string',
274           mandatory    => 1,
275           migrate_from => {
276               use_eval  => 1,
277               formula   => '$old || $older ;',
278               undef_is => "''",
279               variables => {
280                   older => '- Original-Source-Location',
281                   old   => '- Upstream-Source'
282               }
283           },
284        },
285        [qw/Upstream-Source Original-Source-Location/] => {
286           value_type => 'string',
287           status     => 'deprecated',
288           type       => 'leaf'
289        }
290

Examples

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

AUTHOR

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

SEE ALSO

423       Config::Model, Config::Model::Instance, Config::Model::Value
424

AUTHOR

426       Dominique Dumont
427
429       This software is Copyright (c) 2005-2022 by Dominique Dumont.
430
431       This is free software, licensed under:
432
433         The GNU Lesser General Public License, Version 2.1, February 1999
434
435
436
437perl v5.38.0                      2023-07-25 Config::Model::ValueComputer(3pm)
Impressum