NAME
Config::Strict - Add strict name- and type-checking to configuration data
VERSION
0.06 (alpha release)
SYNOPSIS
use Config::Strict;
use Declare::Constraints::Simple -All; # For custom checks
# A comprehensive example
my $config = Config::Strict->new( {
params => { # Parameter types & names
Bool => [ qw( my_bool1 my_bool2 ) ], # Multiple parameters
Int => 'my_i', # Single parameter
Num => 'my_n',
Str => [ qw( my_str1 my_str2 ) ],
Regexp => 'my_re',
ArrayRef => 'my_aref',
HashRef => 'my_href',
CodeRef => 'my_cref',
Enum => { my_enum => [ qw( v1 v2 ), undef ] },
Anon => { # Anon profiles
my_pos2 => # Positive number
And( IsNumber, Matches( qr/^[^-]+$/ ) ),
my_nest => IsA( 'Config::Strict' ), # Nested configuration
}
},
required => [ qw( my_bool1 my_n ) ], # Required parameters
defaults => { # Default values
my_bool1 => 1,
my_str2 => 'str',
my_enum => 'e2',
my_n => -1.1,
my_pos2 => 1_000,
},
} );
# Access and change the data
# Retrieve a single value
$config->get_param( 'my_n' ); # -1.1
# Retrieve a list of values
$config->get_param( qw( my_bool1 my_str2 ) ); # ( 1, 'str' )
# Set multiple parameters
$config->set_param( my_bool1 => 1, 'my_pos2' => 2 );
# Unset parameters
$config->unset_param( 'my_n' );
$config->param_is_set( 'my_n' ); # false
# The following will die:
$config->get_param( 'bad_name' ); # bad_name doesn't exist in the configuration
$config->set_param( 'my_i' => 2.2 ); # my_i must be an integer
$config->set_param( 'my_pos2' => -5 ); # my_pos2 must be positive
DESCRIPTION
Config::Strict wraps Declare::Constraints::Simple to enable strict parameter name- and type-checking on configuration data. That is, it will complain anytime an attempt is made to get or set a parameter value with an invalid name or type; or if an attempt is made to unset a required parameter. Both built-in and custom types can be used to build a validation profile for the entire configuration.
A typical workflow might be:
- 1. Use some configuration module to parse a configuration file and load its data.
- 2. Construct a
Config::Strict
type system for your configuration data. - 3. Load the parsed configuration hash into the Config::Strict object using
set_param
. - 4. Use
get_param
in your program to access configuration values. - 5. Write any changes back to disk using some module.
See Declare::Constraints::Simple::Library for an index to available constraints.
CONSTRUCTING A TYPE SYSTEM
Declare the configuration profile during construction:
new( \%config_profile )
%config_profile
is a multi-level hash with the following top-level keys:
- params (Required)
-
Points to the hash of parameter types and names, where the keys are the built-in Config::Strict types (more below).
The values are either a single parameter name or an arrayref of parameter names, with the exception of the special types
Enum
andAnon
which point to a uniquely defined hashref.Any parameter not named here cannot be added later - any attempt to access a parameter that is not provided in the constructor will result in an error.
Built-In Parameter Types:
- Bool => $param | [ $param1, $param2, ... ]
-
Parameters taking the value 0 or 1.
- Int => $param | [ $param1, $param2, ... ]
-
Integer parameters.
- Num => $param | [ $param1, $param2, ... ]
-
Generic number parameters.
- Str => $param | [ $param1, $param2, ... ]
-
Generic string parameters.
- Enum => { $enum1 => [ $val1, $val2, ... ], ... }
-
Enumerated parameters. The
Enum
key points to a hashref with parameter-values pairs, where valid values for the enumerated parameter are provided as an arrayref.It may be cleaner to instead register your own named enum using
IsOneOf
. (more below)This, along with Anon, is the only exception to the normal declaration syntax.
- Regexp => $param | [ $param1, $param2, ... ]
-
Compiled regexp parameters (with
qr//
). - ArrayRef => $param | [ $param1, $param2, ... ]
-
Generic list parameters.
- HashRef => $param | [ $param1, $param2, ... ]
-
Generic hash parameters.
- CodeRef => $param | [ $param1, $param2, ... ]
-
Generic code parameters.
- Anon => { $param1 => $profile1, ... }
-
Anonymous profiles. The
Anon
key points to a hashref with parameter-profile pairs, where profiles are declared via imported Declare::Constraints::Simple functions. These code profiles will in fact return a Declare::Constraints::Simple::Result which evaluate properly in boolean context along with other additional information when used as an object.Note that, unlike registered profiles (below), anonymous code blocks cannot be used.
- required (Optional)
-
Points to a arrayref of parameter names that must have valid values at all times. These parameters must also be given a default value.
The special value '_all' in the first location is a shortcut to specify that all parameters are to be required.
- defaults (Optional)
-
Points to a hashref of default values to any number of parameters. Those parameters listed in
required
must be present in this section.
USER TYPE REGISTRATION
Aside from the default type built-ins (Bool,Int,...) you can register your own named types to streamline construction and add your own validation logic:
register_types( $name1 => $constraint1, $name2 => $constraint2, ... )
This is a class method.
An example:
use Date::Calc qw(Decode_Month); # For 'FirstQuarter'
# Register user-defined types...
Config::Strict->register_types(
# Normal profiles:
'Private' => Matches( qr/^_/ ),
'ArrayOfAllCaps' => IsArrayRef( Matches( qr/^[A-Z]+$/ ) ),
'LessThan8Chars' => HasLength( 1, 8 ),
'Size' => IsOneOf( qw( small medium large ) ),
# Custom routines:
'FirstQuarter' => sub { Decode_Month($_[0]) <= 4 },
...
);
# ...and use them to make a configuration profile:
my $config = Config::Strict->new( {
params => {
Private => 'myvar',
ArrayOfAllCaps => 'caps',
LessThan8Chars => [ qw( short1 short2 ) ],
Size => 'beverage',
FirstQuarter => 'date_q1',
...
}
}
);
The parameters syntax is the same for that of any of the existing built-ins that take either a single name or arrayref of names. More importantly, they can be used in the same way.
Bare code blocks are automatically converted to named Declare::Constraints::Simple profiles so you can easily provide your own validation logic.
Names cannot duplicate an existing registered type name.
METHODS
GETTING AND SETTING PARAMETER VALUES
These methods will die with a stack trace if a given parameter doesn't exist in the configuration profile, or if an attempt is made to set a parameter with an invalid value.
get_param( $param1, $param2, ... )
Returns the list of values corresponding to each parameter.
set_param( $param1 => $value1, $param2 => $value2, ... )
Sets each parameter-value configuration pair.
unset_param( $param1, $param2, ... )
Unsets each parameter; internally deletes the parameter-value pair from the underlying parameter hash.
Required parameters cannot be unset.
PARAMETER CHECKING
The following methods can be used to check conditions on parameters without killing the program.
validate( $param1 => $value1, $param2 => $value2, ... )
Returns true if all parameter-value pairs are valid; false otherwise.
param_exists( $param )
Returns true if $param
can be get/set; false otherwise.
param_is_set( $param )
Returns true if $param
has been set; false otherwise.
param_is_required( $param )
Returns true if $param
is a required parameter; false otherwise.
OTHER METHODS
all_params()
Returns the list of all parameters in the configuration.
all_set_params()
Returns the list of all set parameters in the configuration.
param_hash()
Returns a copy of the underlying configuration data as a list of key-value pairs.
param_array()
Returns a copy of the underlying configuration data as an array of array references.
get_profile( $param )
Returns the Declare::Constraints::Simple profile used to validate $param
.
EXTENDING THE DEFAULT TYPES (OVERVIEW)
There are several ways to make your type system even more strict than the built-in parameter types:
- 1. Using
register_types
to register your own class-wide types. - 2. Using the
Anon
key and combining any number ofDeclare::Constraints::Simple
profiles. - 3. Subclassing Config::Strict and overloading any of the
_get_check
,_set_check
, and_unset_check
validation methods to add your own general validation semantics. These methods are executed beforeget_param
,set_param
, andunset_param
, respectively.
SEE ALSO
CAVEATS
This is an alpha release - the API is subject to change.
AUTHOR
Blake Willmarth
bwillmarth at gmail.com
BUGS
Please report any bugs or feature requests to bug-config-strict at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-Strict. I will be notified, and then you'll automatically be notified of progress on your bug as changes are made.
LICENSE AND COPYRIGHT
Copyright 2010 Blake Willmarth.
This program is free software; you can redistribute it and/or modify it under the terms of either:
the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or
the Artistic License version 2.0.