NAME

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

SYNOPSIS

my $model = Config::Model->new() ;

$model ->create_config_class 
 (
  name => "Master",
  element 
  => [
      [qw/av bv/] => {type => 'leaf',
                      value_type => 'integer',
                     },
      compute_int 
      => { type => 'leaf',
           value_type => 'integer',
           compute    => [ '$a + $b', a => '- av', b => '- bv' ],
           min        => -4,
           max        => 4,
         },
      [qw/sav sbv/] => {type => 'leaf',
                        value_type => 'string',
                     },
      compute_string =>
      => { type => 'leaf',
           value_type => 'string',
           compute => [ 'meet $a and $b', a => '- sav', b => '- sbv' ],
         },
     ]
) ;

DESCRIPTION

This class provides a way to compute a configuration value. This computation uses a formula and some other configuration values from the configuration tree.

The computed value can be overridden, in other words, the computed value can be used as a defult value.

Computed value declaration

A computed value must be declared in a 'leaf' element. The leaf element must have a compute argument pointing to an array ref.

This array ref contains:

  • A string or a formula that use variables and subsitution function.

  • A set of variable and their relative location in the tree (using the notation explained in grab() method

  • An optional set of substitution rules.

Compute formula

The first element of the compute array ref must be a string that contains the computation algorithm (i.e. a formula for arithmetic computation for integer values or a string template for string values).

This string or formula should contain variables (like $foo or $bar). Note that these variables are not interpolated by perl.

For instance:

'My cat has $nb legs'
'$m * $c**2'

This string or formula may also contain:

  • The index value of the current object : &index or &index().

  • The index value of another object: &index($other)

  • The element name of the current object: &element or &element().

  • The element name of another object: &element($other)

For instance, you could have this template string:

'my element is &element, my index is &index' .
 'upper element is &element($up), upper index is &index($up)',

Compute variables

The following arguments will be a set of key => value to define the variables used in the formula. The key is a variable name used in the computation string. The value is a string that will be used to get the correct Value object.

In this numeric example, result default value is av + bv:

element => [
 av => { 
   type => 'leaf',
   value_type => 'integer'
 },
 bv => { 
   type => 'leaf',
   value_type => 'integer'
 },
 result => { 
   type => 'leaf',
   value_type => 'integer', 
   compute => [ '$a + $b' , a => '- av', b => '- bv' ]
 }

In this string example, the default value of the Comp element is actually a string made of "macro is " and the value of the "macro" element of the object located 2 nodes above:

comp => { 
 type => 'leaf',
 value_type => 'string', 
 compute => [ '"macro is $m"' , m => '- - macro']]
}

Compute substitution

Sometime, using the value of a tree leaf is not enough and you need to substitute a replacement for any value you can get. This replacement can be done using a hash like notation within the formula.

For instance, if you want to display a summary of a config, you can do :

compute => [
  '$munge{$who} is the $munge{$what} of $munge{$country}'
   who   => '! who' ,
   what  => '! what' ,
   country => '- country',
   munge => {  chief => 'president', America => 'USA'}
   ]

Complex formula

&index, &element, and substitution can be combined. But the argument of &element or &index can only be a value object specification (I.e. something like '- - foo'), it cannot be a value replacement of another &element or &index.

I.e. &element($foo) is ok, but &element(&index($foo)) is not allowed.

computed variable

Compute variables can themselves be computed :

compute => [
  'get_element is $element_table{$s}, indirect value is \'$v\'',
  's' => '! $where',
   where => '! where_is_element',
   v => '! $element_table{$s}',
   element_table => { qw/m_value_element m_value compute_element compute/ }
 ]

Be sure not to specify a loop when doing recursive computation.

compute override

In some case, a computed value must be interpreted as a default value and the user must be able to override this computed default value. In this case, you must use allow_compute_override => 1 with the compute parameter:

computed_value_with_override => { 
 type => 'leaf',
 value_type => 'string', 
 allow_compute_override => 1,
 compute => [ '"macro is $m"' , m => '- - macro']
}

AUTHOR

Dominique Dumont, domi@komarr.grenoble.hp.com

SEE ALSO

Config::Model::Model, Config::Model::Instance, Config::Model::Value