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.48
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 in the calling
86       package.
87

SUBROUTINES

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

DECLARATION HELPERS

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

PARAMETERIZED TYPES

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

SUPPORT

321       Bugs may be submitted at
322       <https://github.com/houseabsolute/Specio/issues>.
323

SOURCE

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

AUTHOR

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