NAME
Config::Strict - Add strict name- and type-checking to configuration data
VERSION
0.07 (alpha release)
SYNOPSIS
use Config::Strict;
use Declare::Constraints::Simple -All; # For custom checks
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',
HashRef => 'my_href',
Enum => {
my_enum => [ qw( v1 v2 ), undef ]
},
Anon => { # anonymous 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_enum => 'e2',
my_n => -1.1,
my_pos2 => 1_000,
},
} );
# Access and change the data
# Retrieve a single value
$got = $config->get( 'my_n' ); # $got = -1.1
# Retrieve a list of values
@got = $config->get( qw( my_bool1 my_n ) ); # @got = ( 1, -1.1 )
# Set multiple parameters
$config->set( my_bool1 => 1, 'my_pos2' => 2 );
# Unset parameters
$config->unset( 'my_n' );
$config->param_is_set( 'my_n' ); # false
# The following will die:
$config->get( 'foo' ); # foo doesn't exist
$config->set( 'my_i' => 2.2 ); # my_i must be an integer
$config->set( 'my_pos2' => -5 ); # my_pos2 must be positive
$config->unset( 'my_n' ); # my_n is required
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 access a parameter 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.
This module is meant to be used alongside any configuration parser that hashes configuration data.
See Declare::Constraints::Simple::Library for an index to available constraints.
CONSTRUCTING A TYPE SYSTEM
Declare the configuration profile during construction:
new
$config = Config::Strict->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 '*' (the literal scalar value; not an arrayref) 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
Config::Strict->register_types(
$name1 => $constraint1,
$name2 => $constraint2,
...
);
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
@values = $config->get( $param1, $param2, ... );
Returns the list of values corresponding to each parameter.
set
$config->set( $param1 => $value1, $param2 => $value2, ... );
Sets each parameter-value configuration pair.
unset
$config->unset( $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
$ok = $config->validate( $param1 => $value1, $param2 => $value2, ... );
Returns true if all parameter-value pairs are valid; false otherwise.
param_exists
$ok = $config->param_exists( $param );
Returns true if $param
exists in the configuration; false otherwise.
param_is_set
$ok = $config->param_is_set( $param );
Returns true if $param
has been set; false otherwise.
param_is_required
$ok = $config->param_is_required( $param );
Returns true if $param
is a required parameter; false otherwise.
OTHER METHODS
all_params
@params = $config->all_params();
Returns the list of all parameters in the configuration.
all_set_params
@params = $config->all_set_params();
Returns the list of all set parameters in the configuration.
param_hash
%data = $config->param_hash();
Returns a copy of the underlying configuration data as a list of key-value pairs.
param_array
@data = $config->param_array();
Returns a copy of the underlying configuration data as an array of array references.
get_profile
$profile = $config->get_profile( $param );
Returns the Declare::Constraints::Simple profile used to validate $param
, or undef
if $param
isn't in the profile.
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 of
Declare::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 before "get", "set", and "unset", 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.