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.47
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 $self->parent->inline_check($var)
144                     . ' and more checking code goes here';
145             }
146
147           Or, more concisely:
148
149             sub { $_[0]->parent->inline_check( $_[1] ) . 'more code that checks $_[1]' }
150
151           The "inline" parameter is mutually exclusive with the "where"
152           parameter.
153
154       •   message_generator => sub { ... }
155
156           A subroutine to generate an error message when the type check
157           fails. The default message says something like "Validation failed
158           for type named Int declared in package Specio::Library::Builtins
159           (.../Specio/blib/lib/Specio/Library/Builtins.pm) at line 147 in sub
160           named (eval) with value 1.1".
161
162           You can override this to provide something more specific about the
163           way the type failed.
164
165           The subroutine you provide will be called as a method on the type
166           with two arguments. The first is the description of the type (the
167           bit in the message above that starts with "type named Int ..." and
168           ends with "... in sub named (eval)". This description says what the
169           thing is and where it was defined.
170
171           The second argument is the value that failed the type check, after
172           any coercions that might have been applied.
173
174   anon(...)
175       This subroutine declares an anonymous type. It is identical to
176       "declare" except that it expects a list of key/value parameters without
177       a type name as the first parameter.
178
179   coerce(...)
180       This declares a coercion from one type to another. The first argument
181       should be an object which does the Specio::Constraint::Role::Interface
182       role. This can be either a named or anonymous type. This type is the
183       type that the coercion is to.
184
185       The remaining arguments are key/value parameters:
186
187       •   from => $type
188
189           This must be an object which does the
190           Specio::Constraint::Role::Interface role. This is type that we are
191           coercing from. Again, this can be either a named or anonymous type.
192
193       •   using => sub { ... }
194
195           This is a subroutine which defines the type coercion. It will be
196           passed a single argument, the value to coerce. It should return a
197           new value of the type this coercion is to.
198
199           This parameter is mutually exclusive with the "inline" parameter.
200
201       •   inline => sub { ... }
202
203           This is a subroutine that is called to generate inline code to
204           perform the coercion.
205
206           The inline generator is called as a method on the type with one
207           argument. This argument is a string containing the variable name to
208           use in the generated code. Typically this is something like '$_[0]'
209           or '$value'.
210
211           The inline generator subroutine should return a string of code
212           representing a single term, and it should not be terminated with a
213           semicolon. This allows the inlined code to be safely included in an
214           "if" statement, for example. You can use "do { }" blocks and
215           ternaries to get everything into one term. This single term should
216           evaluate to the new value.
217

DECLARATION HELPERS

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

PARAMETERIZED TYPES

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

SUPPORT

320       Bugs may be submitted at
321       <https://github.com/houseabsolute/Specio/issues>.
322
323       I am also usually active on IRC as 'autarch' on "irc://irc.perl.org".
324

SOURCE

326       The source code repository for Specio can be found at
327       <https://github.com/houseabsolute/Specio>.
328

AUTHOR

330       Dave Rolsky <autarch@urth.org>
331
333       This software is Copyright (c) 2012 - 2021 by Dave Rolsky.
334
335       This is free software, licensed under:
336
337         The Artistic License 2.0 (GPL Compatible)
338
339       The full text of the license can be found in the LICENSE file included
340       with this distribution.
341
342
343
344perl v5.34.0                      2022-01-21                Specio::Declare(3)
Impressum