1Type::Utils(3)        User Contributed Perl Documentation       Type::Utils(3)
2
3
4

NAME

6       Type::Utils - utility functions to make defining and using type
7       constraints a little easier
8

SYNOPSIS

10          package Types::Mine;
11
12          use Type::Library -base;
13          use Type::Utils -all;
14
15          BEGIN { extends "Types::Standard" };
16
17          declare "AllCaps",
18             as "Str",
19             where { uc($_) eq $_ },
20             inline_as { my $varname = $_[1]; "uc($varname) eq $varname" };
21
22          coerce "AllCaps",
23             from "Str", via { uc($_) };
24

STATUS

26       This module is covered by the Type-Tiny stability policy.
27

DESCRIPTION

29       This module provides utility functions to make defining and using type
30       constraints a little easier.
31
32   Type declaration functions
33       Many of the following are similar to the similarly named functions
34       described in Moose::Util::TypeConstraints.
35
36       "declare $name, %options"
37       "declare %options"
38           Declare a named or anonymous type constraint. Use "as" and "where"
39           to specify the parent type (if any) and (possibly) refine its
40           definition.
41
42              declare EvenInt, as Int, where { $_ % 2 == 0 };
43
44              my $EvenInt = declare as Int, where { $_ % 2 == 0 };
45
46           NOTE: If the caller package inherits from Type::Library then any
47           non-anonymous types declared in the package will be automatically
48           installed into the library.
49
50           Hidden gem: if you're inheriting from a type constraint that
51           includes some coercions, you can include "coercion => 1" in the
52           %options hash to inherit the coercions.
53
54       "subtype $name, %options"
55       "subtype %options"
56           Declare a named or anonymous type constraint which is descended
57           from an existing type constraint. Use "as" and "where" to specify
58           the parent type and refine its definition.
59
60           Actually, you should use "declare" instead; this is just an alias.
61
62           This function is not exported by default.
63
64       "type $name, %options"
65       "type %options"
66           Declare a named or anonymous type constraint which is not descended
67           from an existing type constraint. Use "where" to provide a coderef
68           that constrains values.
69
70           Actually, you should use "declare" instead; this is just an alias.
71
72           This function is not exported by default.
73
74       "as $parent"
75           Used with "declare" to specify a parent type constraint:
76
77              declare EvenInt, as Int, where { $_ % 2 == 0 };
78
79       "where { BLOCK }"
80           Used with "declare" to provide the constraint coderef:
81
82              declare EvenInt, as Int, where { $_ % 2 == 0 };
83
84           The coderef operates on $_, which is the value being tested.
85
86       "message { BLOCK }"
87           Generate a custom error message when a value fails validation.
88
89              declare EvenInt,
90                 as Int,
91                 where { $_ % 2 == 0 },
92                 message {
93                    Int->validate($_) or "$_ is not divisible by two";
94                 };
95
96           Without a custom message, the messages generated by Type::Tiny are
97           along the lines of Value "33" did not pass type constraint
98           "EvenInt", which is usually reasonable.
99
100       "inline_as { BLOCK }"
101           Generate a string of Perl code that can be used to inline the type
102           check into other functions. If your type check is being used within
103           a Moose or Moo constructor or accessor methods, or used by
104           Type::Params, this can lead to significant performance
105           improvements.
106
107              declare EvenInt,
108                 as Int,
109                 where { $_ % 2 == 0 },
110                 inline_as {
111                    my ($constraint, $varname) = @_;
112                    my $perlcode =
113                       $constraint->parent->inline_check($varname)
114                       . "&& ($varname % 2 == 0)";
115                    return $perlcode;
116                 };
117
118              warn EvenInt->inline_check('$xxx');  # demonstration
119
120           Experimental: your "inline_as" block can return a list, in which
121           case these will be smushed together with "&&". The first item on
122           the list may be undef, in which case the undef will be replaced by
123           the inlined parent type constraint. (And will throw an exception if
124           there is no parent.)
125
126              declare EvenInt,
127                 as Int,
128                 where { $_ % 2 == 0 },
129                 inline_as {
130                    return (undef, "($_ % 2 == 0)");
131                 };
132
133           Returning a list like this is considered experimental, is not
134           tested very much, and I offer no guarantees that it will
135           necessarily work with Moose/Mouse/Moo.
136
137       "class_type $name, { class => $package, %options }"
138       "class_type { class => $package, %options }"
139       "class_type $name"
140           Shortcut for declaring a Type::Tiny::Class type constraint.
141
142           If $package is omitted, is assumed to be the same as $name.  If
143           $name contains "::" (which would be an invalid name as far as
144           Type::Tiny is concerned), this will be removed.
145
146           So for example, "class_type("Foo::Bar")" declares a
147           Type::Tiny::Class type constraint named "FooBar" which constrains
148           values to objects blessed into the "Foo::Bar" package.
149
150       "role_type $name, { role => $package, %options }"
151       "role_type { role => $package, %options }"
152       "role_type $name"
153           Shortcut for declaring a Type::Tiny::Role type constraint.
154
155           If $package is omitted, is assumed to be the same as $name.  If
156           $name contains "::" (which would be an invalid name as far as
157           Type::Tiny is concerned), this will be removed.
158
159       "duck_type $name, \@methods"
160       "duck_type \@methods"
161           Shortcut for declaring a Type::Tiny::Duck type constraint.
162
163       "union $name, \@constraints"
164       "union \@constraints"
165           Shortcut for declaring a Type::Tiny::Union type constraint.
166
167       "enum $name, \@values"
168       "enum \@values"
169           Shortcut for declaring a Type::Tiny::Enum type constraint.
170
171       "intersection $name, \@constraints"
172       "intersection \@constraints"
173           Shortcut for declaring a Type::Tiny::Intersection type constraint.
174
175   Coercion declaration functions
176       Many of the following are similar to the similarly named functions
177       described in Moose::Util::TypeConstraints.
178
179       "coerce $target, @coercions"
180           Add coercions to the target type constraint. The list of coercions
181           is a list of type constraint, conversion code pairs. Conversion
182           code can be either a string of Perl code or a coderef; in either
183           case the value to be converted is $_.
184
185       "from $source"
186           Sugar to specify a type constraint in a list of coercions:
187
188              coerce EvenInt, from Int, via { $_ * 2 };  # As a coderef...
189              coerce EvenInt, from Int, q { $_ * 2 };    # or as a string!
190
191       "via { BLOCK }"
192           Sugar to specify a coderef in a list of coercions.
193
194       "declare_coercion $name, \%opts, $type1, $code1, ..."
195       "declare_coercion \%opts, $type1, $code1, ..."
196           Declares a coercion that is not explicitly attached to any type in
197           the library. For example:
198
199              declare_coercion "ArrayRefFromAny", from "Any", via { [$_] };
200
201           This coercion will be exportable from the library as a
202           Type::Coercion object, but the ArrayRef type exported by the
203           library won't automatically use it.
204
205           Coercions declared this way are immutable (frozen).
206
207       "to_type $type"
208           Used with "declare_coercion" to declare the target type constraint
209           for a coercion, but still without explicitly attaching the coercion
210           to the type constraint:
211
212              declare_coercion "ArrayRefFromAny",
213                 to_type "ArrayRef",
214                 from "Any", via { [$_] };
215
216           You should pretty much always use this when declaring an unattached
217           coercion because it's exceedingly useful for a type coercion to
218           know what it will coerce to - this allows it to skip coercion when
219           no coercion is needed (e.g. avoiding coercing "[]" to "[ [] ]") and
220           allows "assert_coerce" to work properly.
221
222   Type library management
223       "extends @libraries"
224           Indicates that this type library extends other type libraries,
225           importing their type constraints.
226
227           Should usually be executed in a "BEGIN" block.
228
229           This is not exported by default because it's not fun to export it
230           to Moo, Moose or Mouse classes! "use Type::Utils -all" can be used
231           to import it into your type library.
232
233   Other
234       "match_on_type $value => ($type => \&action, ..., \&default?)"
235           Something like a "switch"/"case" or "given"/"when" construct.
236           Dispatches along different code paths depending on the type of the
237           incoming value.  Example blatantly stolen from the Moose
238           documentation:
239
240              sub to_json
241              {
242                 my $value = shift;
243
244                 return match_on_type $value => (
245                    HashRef() => sub {
246                       my $hash = shift;
247                       '{ '
248                          . (
249                          join ", " =>
250                          map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
251                          sort keys %$hash
252                       ) . ' }';
253                    },
254                    ArrayRef() => sub {
255                       my $array = shift;
256                       '[ '.( join ", " => map { to_json($_) } @$array ).' ]';
257                    },
258                    Num()   => q {$_},
259                    Str()   => q { '"' . $_ . '"' },
260                    Undef() => q {'null'},
261                    => sub { die "$_ is not acceptable json type" },
262                 );
263              }
264
265           Note that unlike Moose, code can be specified as a string instead
266           of a coderef. (e.g. for "Num", "Str" and "Undef" above.)
267
268           For improved performance, try "compile_match_on_type".
269
270           This function is not exported by default.
271
272       "my $coderef = compile_match_on_type($type => \&action, ...,
273       \&default?)"
274           Compile a "match_on_type" block into a coderef. The following JSON
275           converter is about two orders of magnitude faster than the previous
276           example:
277
278              sub to_json;
279              *to_json = compile_match_on_type(
280                 HashRef() => sub {
281                    my $hash = shift;
282                    '{ '
283                       . (
284                       join ", " =>
285                       map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
286                       sort keys %$hash
287                    ) . ' }';
288                 },
289                 ArrayRef() => sub {
290                    my $array = shift;
291                    '[ '.( join ", " => map { to_json($_) } @$array ).' ]';
292                 },
293                 Num()   => q {$_},
294                 Str()   => q { '"' . $_ . '"' },
295                 Undef() => q {'null'},
296                 => sub { die "$_ is not acceptable json type" },
297              );
298
299           Remember to store the coderef somewhere fairly permanent so that
300           you don't compile it over and over. "state" variables (in Perl >=
301           5.10) are good for this. (Same sort of idea as Type::Params.)
302
303           This function is not exported by default.
304
305       "my $coderef = classifier(@types)"
306           Returns a coderef that can be used to classify values according to
307           their type constraint. The coderef, when passed a value, returns a
308           type constraint which the value satisfies.
309
310              use feature qw( say );
311              use Type::Utils qw( classifier );
312              use Types::Standard qw( Int Num Str Any );
313
314              my $classifier = classifier(Str, Int, Num, Any);
315
316              say $classifier->( "42"  )->name;   # Int
317              say $classifier->( "4.2" )->name;   # Num
318              say $classifier->( []    )->name;   # Any
319
320           Note that, for example, "42" satisfies Int, but it would satisfy
321           the type constraints Num, Str, and Any as well. In this case, the
322           classifier has picked the most specific type constraint that "42"
323           satisfies.
324
325           If no type constraint is satisfied by the value, then the
326           classifier will return undef.
327
328       "dwim_type($string, %options)"
329           Given a string like "ArrayRef[Int|CodeRef]", turns it into a type
330           constraint object, hopefully doing what you mean.
331
332           It uses the syntax of Type::Parser. Firstly the Type::Registry for
333           the caller package is consulted; if that doesn't have a match,
334           Types::Standard is consulted for standard type constraint names.
335
336           If none of the above yields a type constraint, and the caller class
337           is a Moose-based class, then "dwim_type" attempts to look the type
338           constraint up in the Moose type registry. If it's a Mouse-based
339           class, then the Mouse type registry is used instead.
340
341           If no type constraint can be found via these normal methods,
342           several fallbacks are available:
343
344           "lookup_via_moose"
345               Lookup in Moose registry even if caller is non-Moose class.
346
347           "lookup_via_mouse"
348               Lookup in Mouse registry even if caller is non-Mouse class.
349
350           "make_class_type"
351               Create a new Type::Tiny::Class constraint.
352
353           "make_role_type"
354               Create a new Type::Tiny::Role constraint.
355
356           You can alter which should be attempted, and in which order, by
357           passing an option to "dwim_type":
358
359              my $type = Type::Utils::dwim_type(
360                 "ArrayRef[Int]",
361                 fallback      => [ "lookup_via_mouse" , "make_role_type" ],
362              );
363
364           For historical reasons, by default the fallbacks attempted are:
365
366              lookup_via_moose, lookup_via_mouse, make_class_type
367
368           You may set "fallback" to an empty arrayref to avoid using any of
369           these fallbacks.
370
371           You can specify an alternative for the caller using the "for"
372           option.
373
374              my $type = dwim_type("ArrayRef", for => "Moose::Object");
375
376           While it's probably better overall to use the proper Type::Registry
377           interface for resolving type constraint strings, this function
378           often does what you want.
379
380           It should never die if it fails to find a type constraint (but may
381           die if the type constraint string is syntactically malformed),
382           preferring to return undef.
383
384           This function is not exported by default.
385
386       "english_list(\$conjunction, @items)"
387           Joins the items with commas, placing a conjunction before the final
388           item.  The conjunction is optional, defaulting to "and".
389
390              english_list(qw/foo bar baz/);       # "foo, bar, and baz"
391              english_list(\"or", qw/quux quuux/); # "quux or quuux"
392
393           This function is not exported by default.
394

EXPORT

396       By default, all of the functions documented above are exported, except
397       "subtype" and "type" (prefer "declare" instead), "extends",
398       "dwim_type", "match_on_type"/"compile_match_on_type", "classifier", and
399       "english_list".
400
401       This module uses Exporter::Tiny; see the documentation of that module
402       for tips and tricks importing from Type::Utils.
403

BUGS

405       Please report any bugs to
406       <http://rt.cpan.org/Dist/Display.html?Queue=Type-Tiny>.
407

SEE ALSO

409       Type::Tiny::Manual.
410
411       Type::Tiny, Type::Library, Types::Standard, Type::Coercion.
412
413       Type::Tiny::Class, Type::Tiny::Role, Type::Tiny::Duck,
414       Type::Tiny::Enum, Type::Tiny::Union.
415
416       Moose::Util::TypeConstraints, Mouse::Util::TypeConstraints.
417

AUTHOR

419       Toby Inkster <tobyink@cpan.org>.
420
422       This software is copyright (c) 2013-2014, 2017-2019 by Toby Inkster.
423
424       This is free software; you can redistribute it and/or modify it under
425       the same terms as the Perl 5 programming language system itself.
426

DISCLAIMER OF WARRANTIES

428       THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
429       WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
430       MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
431
432
433
434perl v5.30.0                      2019-07-26                    Type::Utils(3)
Impressum