1Declare::Constraints::SUismeprleC(o3n)tributed Perl DocuDmeecnltaartei:o:nConstraints::Simple(3)
2
3
4
6 Declare::Constraints::Simple - Declarative Validation of Data
7 Structures
8
10 use Declare::Constraints::Simple-All;
11
12 my $profile = IsHashRef(
13 -keys => HasLength,
14 -values => IsArrayRef( IsObject ));
15
16 my $result1 = $profile->(undef);
17 print $result1->message, "\n"; # 'Not a HashRef'
18
19 my $result2 = $profile->({foo => [23]});
20
21 print $result2->message, "\n"; # 'Not an Object'
22
23 print $result2->path, "\n";
24 # 'IsHashRef[val foo].IsArrayRef[0].IsObject'
25
27 The main purpose of this module is to provide an easy way to build a
28 profile to validate a data structure. It does this by giving you a set
29 of declarative keywords in the importing namespace.
30
32 This is just a brief intro. For details read the documents mentioned in
33 "SEE ALSO".
34
35 Constraint Import
36 use Declare::Constraints::Simple-All;
37
38 The above command imports all constraint generators in the library into
39 the current namespace. If you want only a selection, use "only":
40
41 use Declare::Constraints::Simple
42 Only => qw(IsInt Matches And);
43
44 You can find all constraints (and constraint-like generators, like
45 operators. In fact, "And" above is an operator. They're both
46 implemented equally, so the distinction is a merely philosophical one)
47 documented in the Declare::Constraints::Simple::Library pod. In that
48 document you will also find the exact parameters for their usage, so
49 this here is just a brief Intro and not a coverage of all
50 possibilities.
51
52 Building a Profile
53 You can use these constraints by building a tree that describes what
54 data structure you expect. Every constraint can be used as sub-
55 constraint, as parent, if it accepts other constraints, or stand-alone.
56 If you'd just say
57
58 my $check = IsInt;
59 print "yes!\n" if $check->(23);
60
61 it will work too. This also allows predefining tree segments, and
62 nesting them:
63
64 my $id_to_objects = IsArrayRef(IsObject);
65
66 Here $id_to_objects would give it's OK on an array reference containing
67 a list of objects. But what if we now decide that we actually want a
68 hashref containing two lists of objects? Behold:
69
70 my $object_lists =
71 IsHashRef( HasAllKeys( qw(good bad) ),
72 OnHashKeys( good => $id_to_objects,
73 bad => $id_to_objects ));
74
75 As you can see, constraints like "IsArrayRef" and "IsHashRef" allow you
76 to apply constraints to their keys and values. With this, you can step
77 down in the data structure.
78
79 Applying a Profile to a Data Structure
80 Constraints return just code references that can be applied to one
81 value (and only one value) like this:
82
83 my $result = $object_lists->($value);
84
85 After this call $result contains a Declare::Constraints::Simple::Result
86 object. The first think one wants to know is if the validation
87 succeeded:
88
89 if ($result->is_valid) { ... }
90
91 This is pretty straight forward. To shorten things the result object
92 also overloads it's "bool"ean context. This means you can alternatively
93 just say
94
95 if ($result) { ... }
96
97 However, if the result indicates a invalid data structure, we have a
98 few options to find out what went wrong. There's a human parsable
99 message in the "message" accessor. You can override these by forcing it
100 to a message in a subtree with the "Message" declaration. The "stack"
101 contains the name of the chain of constraints up to the point of
102 failure.
103
104 You can use the "path" accessor for a joined string path representing
105 the stack.
106
107 Creating your own Libraries
108 You can declare a package as a library with
109
110 use Declare::Constraints::Simple-Library;
111
112 which will install the base class and helper methods to define
113 constraints. For a complete list read the documentation in
114 Declare::Constraints::Simple::Library::Base. You can use other
115 libraries as base classes to include their constraints in your export
116 possibilities. This means that with a package setup like
117
118 package MyLibrary;
119 use warnings;
120 use strict;
121
122 use Declare::Constraints::Simple-Library;
123 use base 'Declare::Constraints::Simple::Library';
124
125 constraint 'MyConstraint',
126 sub { return _result(($_[0] >= 12), 'Value too small') };
127
128 1;
129
130 you can do
131
132 use MyLibrary-All;
133
134 and have all constraints, from the default library and yours from
135 above, installed into your requesting namespace. You can override a
136 constraint just by redeclaring it in a subclass.
137
138 Scoping
139 Sometimes you want to validate parts of a data structure depending on
140 another part of it. As of version 2.0 you can declare scopes and store
141 results in them. Here is a complete example:
142
143 my $constraint =
144 Scope('foo',
145 And(
146 HasAllKeys( qw(cmd data) ),
147 OnHashKeys(
148 cmd => Or( SetResult('foo', 'cmd_a',
149 IsEq('FOO_A')),
150 SetResult('foo', 'cmd_b',
151 IsEq('FOO_B')) ),
152 data => Or( And( IsValid('foo', 'cmd_a'),
153 IsArrayRef( IsInt )),
154 And( IsValid('foo', 'cmd_b'),
155 IsRegex )) )));
156
157 This profile would accept a hash references with the keys "cmd" and
158 "data". If "cmd" is set to "FOO_A", then "data" has to be an array ref
159 of integers. But if "cmd" is set to "FOO_B", a regular expression is
160 expected.
161
163 Declare::Constraints::Simple::Library,
164 Declare::Constraints::Simple::Result,
165 Declare::Constraints::Simple::Base, Module::Install
166
168 Carp::Clan, aliased, Class::Inspector, Scalar::Util, overload and
169 Test::More (for build).
170
172 · Examples.
173
174 · A list of questions that might come up, together with their
175 answers.
176
177 · A "Custom" constraint that takes a code reference.
178
179 · Create stack objects that stringify to the current form, but can
180 hold more data.
181
182 · Give the "Message" constraint the ability to get the generated
183 constraint inserted in the message. A possibility would be to
184 replace __Value__ and __Message__. It might also accept code
185 references, which return strings.
186
187 · Allow the "IsCodeRef" constraint to accept further constraints. One
188 might like to check, for example, the refaddr of a closure.
189
190 · A "Captures" constraint that takes a regex and can apply other
191 constraints to the matches.
192
193 · ???
194
195 · Profit.
196
198 perl Makefile.PL
199 make
200 make test
201 make install
202
203 For details read Module::Install.
204
206 Robert 'phaylon' Sedlacek "<phaylon@dunkelheit.at>"
207
209 This module is free software, you can redistribute it and/or modify it
210 under the same terms as perl itself.
211
212
213
214perl v5.30.0 2019-07-26 Declare::Constraints::Simple(3)