1Specio::Declare(3)    User Contributed Perl Documentation   Specio::Declare(3)
2
3
4

NAME

6       Specio::Declare - Specio declaration subroutines
7

VERSION

9       version 0.42
10

SYNOPSIS

12           package MyApp::Type::Library;
13
14           use parent 'Specio::Exporter';
15
16           use Specio::Declare;
17           use Specio::Library::Builtins;
18
19           declare(
20               'Foo',
21               parent => t('Str'),
22               where  => sub { $_[0] =~ /foo/i },
23           );
24
25           declare(
26               'ArrayRefOfInt',
27               parent => t( 'ArrayRef', of => t('Int') ),
28           );
29
30           my $even = anon(
31               parent => t('Int'),
32               inline => sub {
33                   my $type      = shift;
34                   my $value_var = shift;
35
36                   return $value_var . ' % 2 == 0';
37               },
38           );
39
40           coerce(
41               t('ArrayRef'),
42               from  => t('Foo'),
43               using => sub { [ $_[0] ] },
44           );
45
46           coerce(
47               $even,
48               from  => t('Int'),
49               using => sub { $_[0] % 2 ? $_[0] + 1 : $_[0] },
50           );
51
52           # Specio name is DateTime
53           any_isa_type('DateTime');
54
55           # Specio name is DateTimeObject
56           object_isa_type( 'DateTimeObject', class => 'DateTime' );
57
58           any_can_type(
59               'Duck',
60               methods => [ 'duck_walk', 'quack' ],
61           );
62
63           object_can_type(
64               'DuckObject',
65               methods => [ 'duck_walk', 'quack' ],
66           );
67
68           enum(
69               'Colors',
70               values => [qw( blue green red )],
71           );
72
73           intersection(
74               'HashRefAndArrayRef',
75               of => [ t('HashRef'), t('ArrayRef') ],
76           );
77
78           union(
79               'IntOrArrayRef',
80               of => [ t('Int'), t('ArrayRef') ],
81           );
82

DESCRIPTION

84       This package exports a set of type declaration helpers. Importing this
85       package also causes it to create a "t" subroutine the caller.
86

SUBROUTINES

88       This module exports the following subroutines.
89
90   t('name')
91       This subroutine lets you access any types you have declared so far, as
92       well as any types you imported from another type library.
93
94       If you pass an unknown name, it throws an exception.
95
96   declare(...)
97       This subroutine declares a named type. The first argument is the type
98       name, followed by a set of key/value parameters:
99
100       ·   parent => $type
101
102           The parent should be another type object. Specifically, it can be
103           anything which does the Specio::Constraint::Role::Interface role.
104           The parent can be a named or anonymous type.
105
106       ·   where => sub { ... }
107
108           This is a subroutine which defines the type constraint. It will be
109           passed a single argument, the value to check, and it should return
110           true or false to indicate whether or not the value is valid for the
111           type.
112
113           This parameter is mutually exclusive with the "inline" parameter.
114
115       ·   inline => sub { ... }
116
117           This is a subroutine that is called to generate inline code to
118           validate the type. Inlining can be much faster than simply
119           providing a subroutine with the "where" parameter, but is often
120           more complicated to get right.
121
122           The inline generator is called as a method on the type with one
123           argument. This argument is a string containing the variable name to
124           use in the generated code. Typically this is something like '$_[0]'
125           or '$value'.
126
127           The inline generator subroutine should return a string of code
128           representing a single term, and it should not be terminated with a
129           semicolon. This allows the inlined code to be safely included in an
130           "if" statement, for example. You can use "do { }" blocks and
131           ternaries to get everything into one term. Do not assign to the
132           variable you are testing. This single term should evaluate to true
133           or false.
134
135           The inline generator is expected to include code to implement both
136           the current type and all its parents. Typically, the easiest way to
137           do this is to write a subroutine something like this:
138
139             sub {
140                 my $self = shift;
141                 my $var  = shift;
142
143                 return $_[0]->parent->inline_check( $_[1] )
144                     . ' and more checking code goes here';
145             }
146
147           This parameter is mutually exclusive with the "where" parameter.
148
149       ·   message_generator => sub { ... }
150
151           A subroutine to generate an error message when the type check
152           fails. The default message says something like "Validation failed
153           for type named Int declared in package Specio::Library::Builtins
154           (.../Specio/blib/lib/Specio/Library/Builtins.pm) at line 147 in sub
155           named (eval) with value 1.1".
156
157           You can override this to provide something more specific about the
158           way the type failed.
159
160           The subroutine you provide will be called as a method on the type
161           with two arguments. The first is the description of the type (the
162           bit in the message above that starts with "type named Int ..." and
163           ends with "... in sub named (eval)". This description says what the
164           thing is and where it was defined.
165
166           The second argument is the value that failed the type check, after
167           any coercions that might have been applied.
168
169   anon(...)
170       This subroutine declares an anonymous type. It is identical to
171       "declare" except that it expects a list of key/value parameters without
172       a type name as the first parameter.
173
174   coerce(...)
175       This declares a coercion from one type to another. The first argument
176       should be an object which does the Specio::Constraint::Role::Interface
177       role. This can be either a named or anonymous type. This type is the
178       type that the coercion is to.
179
180       The remaining arguments are key/value parameters:
181
182       ·   from => $type
183
184           This must be an object which does the
185           Specio::Constraint::Role::Interface role. This is type that we are
186           coercing from. Again, this can be either a named or anonymous type.
187
188       ·   using => sub { ... }
189
190           This is a subroutine which defines the type coercion. It will be
191           passed a single argument, the value to coerce. It should return a
192           new value of the type this coercion is to.
193
194           This parameter is mutually exclusive with the "inline" parameter.
195
196       ·   inline => sub { ... }
197
198           This is a subroutine that is called to generate inline code to
199           perform the coercion.
200
201           The inline generator is called as a method on the type with one
202           argument. This argument is a string containing the variable name to
203           use in the generated code. Typically this is something like '$_[0]'
204           or '$value'.
205
206           The inline generator subroutine should return a string of code
207           representing a single term, and it should not be terminated with a
208           semicolon. This allows the inlined code to be safely included in an
209           "if" statement, for example. You can use "do { }" blocks and
210           ternaries to get everything into one term. This single term should
211           evaluate to the new value.
212

DECLARATION HELPERS

214       This module also exports some helper subs for declaring certain kinds
215       of types:
216
217   any_isa_type, object_isa_type
218       The "any_isa_type" helper creates a type which accepts a class name or
219       object of the given class. The "object_isa_type" helper creates a type
220       which only accepts an object of the given class.
221
222       These subroutines take a type name as the first argument. The remaining
223       arguments are key/value pairs. Currently this is just the "class" key,
224       which should be a class name. This is the class that the type requires.
225
226       The type name argument can be omitted to create an anonymous type.
227
228       You can also pass just a single argument, in which case that will be
229       used as both the type's name and the class for the constraint to check.
230
231   any_does_type, object_does_type
232       The "any_does_type" helper creates a type which accepts a class name or
233       object which does the given role. The "object_does_type" helper creates
234       a type which only accepts an object which does the given role.
235
236       These subroutines take a type name as the first argument. The remaining
237       arguments are key/value pairs. Currently this is just the "role" key,
238       which should be a role name. This is the class that the type requires.
239
240       This should just work (I hope) with roles created by Moose, Mouse, and
241       Moo (using Role::Tiny).
242
243       The type name argument can be omitted to create an anonymous type.
244
245       You can also pass just a single argument, in which case that will be
246       used as both the type's name and the role for the constraint to check.
247
248   any_can_type, object_can_type
249       The "any_can_type" helper creates a type which accepts a class name or
250       object with the given methods. The "object_can_type" helper creates a
251       type which only accepts an object with the given methods.
252
253       These subroutines take a type name as the first argument. The remaining
254       arguments are key/value pairs. Currently this is just the "methods"
255       key, which can be either a string or array reference of strings. These
256       strings are the required methods for the type.
257
258       The type name argument can be omitted to create an anonymous type.
259
260   enum
261       This creates a type which accepts a string matching a given list of
262       acceptable values.
263
264       The first argument is the type name. The remaining arguments are
265       key/value pairs. Currently this is just the "values" key. This should
266       an array reference of acceptable string values.
267
268       The type name argument can be omitted to create an anonymous type.
269
270   intersection
271       This creates a type which is the intersection of two or more other
272       types. A union only accepts values which match all of its underlying
273       types.
274
275       The first argument is the type name. The remaining arguments are
276       key/value pairs. Currently this is just the "of" key. This should an
277       array reference of types.
278
279       The type name argument can be omitted to create an anonymous type.
280
281   union
282       This creates a type which is the union of two or more other types. A
283       union accepts any of its underlying types.
284
285       The first argument is the type name. The remaining arguments are
286       key/value pairs. Currently this is just the "of" key. This should an
287       array reference of types.
288
289       The type name argument can be omitted to create an anonymous type.
290

PARAMETERIZED TYPES

292       You can create a parameterized type by calling "t" with additional
293       parameters, like this:
294
295         my $arrayref_of_int = t( 'ArrayRef', of => t('Int') );
296
297         my $arrayref_of_hashref_of_int = t(
298             'ArrayRef',
299             of => t(
300                 'HashRef',
301                 of => t('Int'),
302             ),
303         );
304
305       The "t" subroutine assumes that if it receives more than one argument,
306       it should look up the named type and call "$type->parameterize(...)"
307       with the additional arguments.
308
309       If the named type cannot be parameterized, it throws an error.
310
311       You can also call "$type->parameterize" directly if needed. See
312       Specio::Constraint::Parameterizable for details.
313

SUPPORT

315       Bugs may be submitted at
316       <https://github.com/houseabsolute/Specio/issues>.
317
318       I am also usually active on IRC as 'autarch' on "irc://irc.perl.org".
319

SOURCE

321       The source code repository for Specio can be found at
322       <https://github.com/houseabsolute/Specio>.
323

AUTHOR

325       Dave Rolsky <autarch@urth.org>
326
328       This software is Copyright (c) 2012 - 2017 by Dave Rolsky.
329
330       This is free software, licensed under:
331
332         The Artistic License 2.0 (GPL Compatible)
333
334       The full text of the license can be found in the LICENSE file included
335       with this distribution.
336
337
338
339perl v5.28.0                      2017-11-04                Specio::Declare(3)
Impressum