This is just a brief intro. For details read the documents mentioned in "SEE ALSO".
ConstraintImport
use Declare::Constraints::Simple-All;
The above command imports all constraint generators in the library into the current namespace. If you
want only a selection, use "only":
use Declare::Constraints::Simple
Only => qw(IsInt Matches And);
You can find all constraints (and constraint-like generators, like operators. In fact, "And" above is an
operator. They're both implemented equally, so the distinction is a merely philosophical one) documented
in the Declare::Constraints::Simple::Library pod. In that document you will also find the exact
parameters for their usage, so this here is just a brief Intro and not a coverage of all possibilities.
BuildingaProfile
You can use these constraints by building a tree that describes what data structure you expect. Every
constraint can be used as sub-constraint, as parent, if it accepts other constraints, or stand-alone. If
you'd just say
my $check = IsInt;
print "yes!\n" if $check->(23);
it will work too. This also allows predefining tree segments, and nesting them:
my $id_to_objects = IsArrayRef(IsObject);
Here $id_to_objects would give it's OK on an array reference containing a list of objects. But what if we
now decide that we actually want a hashref containing two lists of objects? Behold:
my $object_lists =
IsHashRef( HasAllKeys( qw(good bad) ),
OnHashKeys( good => $id_to_objects,
bad => $id_to_objects ));
As you can see, constraints like "IsArrayRef" and "IsHashRef" allow you to apply constraints to their
keys and values. With this, you can step down in the data structure.
ApplyingaProfiletoaDataStructure
Constraints return just code references that can be applied to one value (and only one value) like this:
my $result = $object_lists->($value);
After this call $result contains a Declare::Constraints::Simple::Result object. The first think one wants
to know is if the validation succeeded:
if ($result->is_valid) { ... }
This is pretty straight forward. To shorten things the result object also overloads it's "bool"ean
context. This means you can alternatively just say
if ($result) { ... }
However, if the result indicates a invalid data structure, we have a few options to find out what went
wrong. There's a human parsable message in the "message" accessor. You can override these by forcing it
to a message in a subtree with the "Message" declaration. The "stack" contains the name of the chain of
constraints up to the point of failure.
You can use the "path" accessor for a joined string path representing the stack.
CreatingyourownLibraries
You can declare a package as a library with
use Declare::Constraints::Simple-Library;
which will install the base class and helper methods to define constraints. For a complete list read the
documentation in Declare::Constraints::Simple::Library::Base. You can use other libraries as base classes
to include their constraints in your export possibilities. This means that with a package setup like
package MyLibrary;
use warnings;
use strict;
use Declare::Constraints::Simple-Library;
use base 'Declare::Constraints::Simple::Library';
constraint 'MyConstraint',
sub { return _result(($_[0] >= 12), 'Value too small') };
1;
you can do
use MyLibrary-All;
and have all constraints, from the default library and yours from above, installed into your requesting
namespace. You can override a constraint just by redeclaring it in a subclass.
Scoping
Sometimes you want to validate parts of a data structure depending on another part of it. As of version
2.0 you can declare scopes and store results in them. Here is a complete example:
my $constraint =
Scope('foo',
And(
HasAllKeys( qw(cmd data) ),
OnHashKeys(
cmd => Or( SetResult('foo', 'cmd_a',
IsEq('FOO_A')),
SetResult('foo', 'cmd_b',
IsEq('FOO_B')) ),
data => Or( And( IsValid('foo', 'cmd_a'),
IsArrayRef( IsInt )),
And( IsValid('foo', 'cmd_b'),
IsRegex )) )));
This profile would accept a hash references with the keys "cmd" and "data". If "cmd" is set to "FOO_A",
then "data" has to be an array ref of integers. But if "cmd" is set to "FOO_B", a regular expression is
expected.