Config::Model::Value.3pm

Langue: en

Version: 2010-08-18 (fedora - 01/12/10)

Section: 3 (Bibliothèques de fonctions)

NAME

Config::Model::Value - Strongly typed configuration value

VERSION

version 1.205

SYNOPSIS

  my $model = Config::Model->new() ;
  $model ->create_config_class 
   (
    name => "SomeClass",
    element => [
      country => { 
        type =>       'leaf',
        value_type => 'enum',
        choice =>      [qw/France US/]
      },
      president => { 
        type =>        'leaf',
        value_type => 'string',
        warp => { 
          follow => { c => '- country'}, 
          rules  => {
            '$c eq "France"' => { default => 'Chirac' },
            '$c eq "US"'     => { default => 'Bush' }
          }
        },
      }
    ]
  );
 
 

DESCRIPTION

This class provides a way to specify configuration value with the following properties:
*
Strongly typed scalar: the value can either be an enumerated type, a boolean, a number, an integer or a string
*
default parameter: a value can have a default value specified during the construction. This default value will be written in the target configuration file. ("default" parameter)
*
upstream default parameter: specifies a default value that will be used by the application when no information is provided in the configuration file. This upstream_default value will not written in the configuration files. Only the "fetch_standard" method will return the builtin value. This parameter was previously refered as "built_in" value. This may be used for audit purpose. ("upstream_default" parameter)
*
mandatory value: reading a mandatory value will raise an exception if the value is not specified 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'.
*
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''.

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 knows in the application, 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 Config::Model::Instance/``preset_start ()''

Then there is the value entered by the user. This will override all kind of ``default'' value.

The fetch_standard function will return the ``highest'' level of default value, but will not return a custom value, i.e. a value entered by the user.

Constructor

Value object should not be created directly.

Value model declaration

A leaf element must be declared with the following parameters:
value_type
Either "boolean", "enum", "integer", "number", "uniline", "string". Mandatory. See ``Value types''.
default
Specify the default value (optional)
upstream_default
Specify a built in default value (optional)
compute
Will compute a value according to a formula and other values. By default a computed value cannot be set. See Config::Model::ValueComputer for computed value declaration.
migrate_from
This is a special parameter to cater for smooth configuration upgrade. This parameter can be used to copy the value of a deprecated parameter to its replacement. See ``upgrade''`` in '' for details.
convert => [uc | lc ]
When stored, the value will be 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 value of an enum. Example :
  choice => [ qw/foo bar/]
 
 
match
Perl regular expression. The value will be match with the regex to assert its validity. Example "match => '^foo'" means that the parameter value must begin with ``foo''. Valid only for "string" or "uniline" values.
replace
Hash ref. Used for enum to substitute one value with another. This parameter must be used to enable user to upgrade a configuration with obsolete values. For instance, if the value "foo" is obsolete and replaced by "foo_better", you will need to declare:
   replace => { foo => 'foo_better' }
 
 
refer_to
Specify a path to an id element used as a reference. See Value Reference for details.
computed_refer_to
Specify a pathto an id element used as a computed reference. See ``Value Reference'' for details.
warp
See section below: ``Warp: dynamic value configuration''.
help
You may provide detailed description on possible values with a hash ref. Example:
  help => { oui => "French for 'yes'", non => "French for 'no'"}
 
 

Value types

This modules can check several value types:
boolean
Accepts values 1 or 0, "yes" or "no", "true" or "false". The value read back is always 1 or 0.
enum
Enum choices must be specified by the "choice" parameter.
integer
Enable positive or negative integer
number
The value can be a decimal number
uniline
A one line string. I.e without ``\n'' in it.
string
Actually, no check is performed with this type.
reference
Like an "enum" where the possible values (aka choice) is defined by another location if the configuration tree. See ``Value Reference''.

Warp: dynamic value configuration

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::WarpedThing 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 => {
        type => 'leaf',
        value_type => 'enum',
        choice => [qw/PAL NTSC SECAM/]  
        warp => { 
          follow => { c => '- country' }, # this points to the warp master
          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" will mean 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' ]}
          }
       }
    }
 
 

Cascaded warping

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:
*
Warp loop are not detected and will end up in ``deep recursion subroutine'' failures.
*
If you declare ``diamond'' shaped warp dependencies, the results will depend on the order of the warp algorithm and can be unpredictable.
*
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 will be silently ignored during start up and will fail at run time.

Value Reference

To set up an enumerated value where the possible choice depends on the key of a Config::Model::AnyId object, you must:
*
Set "value_type" to "reference".
*
Specify the "refer_to" or "computed_refer_to" parameter. See refer_to parameter.

In this case, a "IdElementReference" object is created to handle the relation between this value object and the refered Id. See Config::Model::IdElementReference for details.

Introspection methods

The following methods returns the current value of the parameter of the value object (as declared in the model unless they were warped):
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. Return 0 for a read-only value (i.e. a computed value with no override allowed).

get_choice()

Query legal values (only for enum types). Return an array (possibly empty).

get_help ( [ on_value ] )

Returns the help strings passed to the constructor.

With "on_value" parameter, returns the help string dedicated to the passed value or undef.

Without parameter returns a hash ref that contains all the help strings.

check_value ( value , [ 0 | 1 ] )

Check the consistency of the value. Does not check for undefined mandatory values.

When the 2nd parameter is non null, check will 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, 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.

check( value , [ 0 | 1 ] )

Like ``check_value''. Also ensure that mandatory value are defined

Information management

store( value )

Store value in leaf element.

load_data( scalar_value )

Load scalar data. Data is simply forwarded to store.

fetch_custom

Returns the stored value if this value is different from a standard setting or built in seting. In other words, returns undef if the stored value is identical to the default value or the computed value or the built in value.

fetch_standard

Returns the standard value as defined by the configuration model. The standard value can be either a preset value, a computed value, a default value or a built-in default value.

fetch_no_check

Fetch value from leaf element without checking the value.

fetch( [ custom | preset | standard | default ] )

Check and fetch value from leaf element.

With a parameter, this method will return either:

custom
The value entered by the user (if different from built in, preset, computed or default value)
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)
upstream_default
The upstream_default value. (defined by the configuration model)
non_upstream_default
The custom or preset or computed or default value. Will return undef if either of this value is identical to the upstream_default value. This feature is useful to reduce data to write in configuration file.
allow_undef
This mode will accept to return undef for mandatory values. Normally, trying to fetch an undefined manadatory value leads to an exception.

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.

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.

get( path , [ custom | preset | standard | default ])

Get a value from a directory like path.

set( path , value )

Set a value from a directory like path.

Upgrade

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:

*
Declare the deprecated parameter with a "status" set to "deprecated"
*
Declare the new parameter with the intructions 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 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.

AUTHOR

Dominique Dumont, (ddumont at cpan dot org)

SEE ALSO

Config::Model, Config::Model::Node, Config::Model::AnyId, Config::Model::WarpedThing, Exception::Class Config::Model::ValueComputer,