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           Your "inline_as" block can return a list, in which case these will
121           be smushed together with "&&". The first item on the list may be
122           undef, in which case the undef will be replaced by the inlined
123           parent type constraint. (And will throw an exception if there is no
124           parent.)
125
126              declare EvenInt,
127                 as Int,
128                 where { $_ % 2 == 0 },
129                 inline_as {
130                    return (undef, "($_ % 2 == 0)");
131                 };
132
133       "class_type $name, { class => $package, %options }"
134       "class_type { class => $package, %options }"
135       "class_type $name"
136           Shortcut for declaring a Type::Tiny::Class type constraint.
137
138           If $package is omitted, is assumed to be the same as $name.  If
139           $name contains "::" (which would be an invalid name as far as
140           Type::Tiny is concerned), this will be removed.
141
142           So for example, "class_type("Foo::Bar")" declares a
143           Type::Tiny::Class type constraint named "FooBar" which constrains
144           values to objects blessed into the "Foo::Bar" package.
145
146       "role_type $name, { role => $package, %options }"
147       "role_type { role => $package, %options }"
148       "role_type $name"
149           Shortcut for declaring a Type::Tiny::Role type constraint.
150
151           If $package is omitted, is assumed to be the same as $name.  If
152           $name contains "::" (which would be an invalid name as far as
153           Type::Tiny is concerned), this will be removed.
154
155       "duck_type $name, \@methods"
156       "duck_type \@methods"
157           Shortcut for declaring a Type::Tiny::Duck type constraint.
158
159       "union $name, \@constraints"
160       "union \@constraints"
161           Shortcut for declaring a Type::Tiny::Union type constraint.
162
163       "enum $name, \@values"
164       "enum \@values"
165           Shortcut for declaring a Type::Tiny::Enum type constraint.
166
167       "intersection $name, \@constraints"
168       "intersection \@constraints"
169           Shortcut for declaring a Type::Tiny::Intersection type constraint.
170
171   Coercion declaration functions
172       Many of the following are similar to the similarly named functions
173       described in Moose::Util::TypeConstraints.
174
175       "coerce $target, @coercions"
176           Add coercions to the target type constraint. The list of coercions
177           is a list of type constraint, conversion code pairs. Conversion
178           code can be either a string of Perl code or a coderef; in either
179           case the value to be converted is $_.
180
181       "from $source"
182           Sugar to specify a type constraint in a list of coercions:
183
184              coerce EvenInt, from Int, via { $_ * 2 };  # As a coderef...
185              coerce EvenInt, from Int, q { $_ * 2 };    # or as a string!
186
187       "via { BLOCK }"
188           Sugar to specify a coderef in a list of coercions.
189
190       "declare_coercion $name, \%opts, $type1, $code1, ..."
191       "declare_coercion \%opts, $type1, $code1, ..."
192           Declares a coercion that is not explicitly attached to any type in
193           the library. For example:
194
195              declare_coercion "ArrayRefFromAny", from "Any", via { [$_] };
196
197           This coercion will be exportable from the library as a
198           Type::Coercion object, but the ArrayRef type exported by the
199           library won't automatically use it.
200
201           Coercions declared this way are immutable (frozen).
202
203       "to_type $type"
204           Used with "declare_coercion" to declare the target type constraint
205           for a coercion, but still without explicitly attaching the coercion
206           to the type constraint:
207
208              declare_coercion "ArrayRefFromAny",
209                 to_type "ArrayRef",
210                 from "Any", via { [$_] };
211
212           You should pretty much always use this when declaring an unattached
213           coercion because it's exceedingly useful for a type coercion to
214           know what it will coerce to - this allows it to skip coercion when
215           no coercion is needed (e.g. avoiding coercing "[]" to "[ [] ]") and
216           allows "assert_coerce" to work properly.
217
218   Type library management
219       "extends @libraries"
220           Indicates that this type library extends other type libraries,
221           importing their type constraints.
222
223           Should usually be executed in a "BEGIN" block.
224
225           This is not exported by default because it's not fun to export it
226           to Moo, Moose or Mouse classes! "use Type::Utils -all" can be used
227           to import it into your type library.
228
229   Other
230       "match_on_type $value => ($type => \&action, ..., \&default?)"
231           Something like a "switch"/"case" or "given"/"when" construct.
232           Dispatches along different code paths depending on the type of the
233           incoming value.  Example blatantly stolen from the Moose
234           documentation:
235
236              sub to_json
237              {
238                 my $value = shift;
239
240                 return match_on_type $value => (
241                    HashRef() => sub {
242                       my $hash = shift;
243                       '{ '
244                          . (
245                          join ", " =>
246                          map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
247                          sort keys %$hash
248                       ) . ' }';
249                    },
250                    ArrayRef() => sub {
251                       my $array = shift;
252                       '[ '.( join ", " => map { to_json($_) } @$array ).' ]';
253                    },
254                    Num()   => q {$_},
255                    Str()   => q { '"' . $_ . '"' },
256                    Undef() => q {'null'},
257                    => sub { die "$_ is not acceptable json type" },
258                 );
259              }
260
261           Note that unlike Moose, code can be specified as a string instead
262           of a coderef. (e.g. for "Num", "Str" and "Undef" above.)
263
264           For improved performance, try "compile_match_on_type".
265
266           This function is not exported by default.
267
268       "my $coderef = compile_match_on_type($type => \&action, ...,
269       \&default?)"
270           Compile a "match_on_type" block into a coderef. The following JSON
271           converter is about two orders of magnitude faster than the previous
272           example:
273
274              sub to_json;
275              *to_json = compile_match_on_type(
276                 HashRef() => sub {
277                    my $hash = shift;
278                    '{ '
279                       . (
280                       join ", " =>
281                       map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
282                       sort keys %$hash
283                    ) . ' }';
284                 },
285                 ArrayRef() => sub {
286                    my $array = shift;
287                    '[ '.( join ", " => map { to_json($_) } @$array ).' ]';
288                 },
289                 Num()   => q {$_},
290                 Str()   => q { '"' . $_ . '"' },
291                 Undef() => q {'null'},
292                 => sub { die "$_ is not acceptable json type" },
293              );
294
295           Remember to store the coderef somewhere fairly permanent so that
296           you don't compile it over and over. "state" variables (in Perl >=
297           5.10) are good for this. (Same sort of idea as Type::Params.)
298
299           This function is not exported by default.
300
301       "my $coderef = classifier(@types)"
302           Returns a coderef that can be used to classify values according to
303           their type constraint. The coderef, when passed a value, returns a
304           type constraint which the value satisfies.
305
306              use feature qw( say );
307              use Type::Utils qw( classifier );
308              use Types::Standard qw( Int Num Str Any );
309
310              my $classifier = classifier(Str, Int, Num, Any);
311
312              say $classifier->( "42"  )->name;   # Int
313              say $classifier->( "4.2" )->name;   # Num
314              say $classifier->( []    )->name;   # Any
315
316           Note that, for example, "42" satisfies Int, but it would satisfy
317           the type constraints Num, Str, and Any as well. In this case, the
318           classifier has picked the most specific type constraint that "42"
319           satisfies.
320
321           If no type constraint is satisfied by the value, then the
322           classifier will return undef.
323
324       "dwim_type($string, %options)"
325           Given a string like "ArrayRef[Int|CodeRef]", turns it into a type
326           constraint object, hopefully doing what you mean.
327
328           It uses the syntax of Type::Parser. Firstly the Type::Registry for
329           the caller package is consulted; if that doesn't have a match,
330           Types::Standard is consulted for standard type constraint names.
331
332           If none of the above yields a type constraint, and the caller class
333           is a Moose-based class, then "dwim_type" attempts to look the type
334           constraint up in the Moose type registry. If it's a Mouse-based
335           class, then the Mouse type registry is used instead.
336
337           If no type constraint can be found via these normal methods,
338           several fallbacks are available:
339
340           "lookup_via_moose"
341               Lookup in Moose registry even if caller is non-Moose class.
342
343           "lookup_via_mouse"
344               Lookup in Mouse registry even if caller is non-Mouse class.
345
346           "make_class_type"
347               Create a new Type::Tiny::Class constraint.
348
349           "make_role_type"
350               Create a new Type::Tiny::Role constraint.
351
352           You can alter which should be attempted, and in which order, by
353           passing an option to "dwim_type":
354
355              my $type = Type::Utils::dwim_type(
356                 "ArrayRef[Int]",
357                 fallback      => [ "lookup_via_mouse" , "make_role_type" ],
358              );
359
360           For historical reasons, by default the fallbacks attempted are:
361
362              lookup_via_moose, lookup_via_mouse, make_class_type
363
364           You may set "fallback" to an empty arrayref to avoid using any of
365           these fallbacks.
366
367           You can specify an alternative for the caller using the "for"
368           option.
369
370              my $type = dwim_type("ArrayRef", for => "Moose::Object");
371
372           While it's probably better overall to use the proper Type::Registry
373           interface for resolving type constraint strings, this function
374           often does what you want.
375
376           It should never die if it fails to find a type constraint (but may
377           die if the type constraint string is syntactically malformed),
378           preferring to return undef.
379
380           This function is not exported by default.
381
382       "is($type, $value)"
383           Shortcut for "$type->check($value)" but also if $type is a string,
384           will look it up via "dwim_type".
385
386           This function is not exported by default.  This function is not
387           even exported by "use Type::Utils -all".  You must request it
388           explicitly.
389
390             use Type::Utils "is";
391
392           Beware using this in test scripts because it has the same name as a
393           function exported by Test::More. Note that you can rename this
394           function if "is" will cause conflicts:
395
396              use Type::Utils "is" => { -as => "isntnt" };
397
398       "assert($type, $value)"
399           Like "is" but instead of returning a boolean, returns $value and
400           dies if the value fails the type check.
401
402           This function is not exported by default, but it is exported by
403           "use Type::Utils -all".
404
405       "english_list(\$conjunction, @items)"
406           Joins the items with commas, placing a conjunction before the final
407           item.  The conjunction is optional, defaulting to "and".
408
409              english_list(qw/foo bar baz/);       # "foo, bar, and baz"
410              english_list(\"or", qw/quux quuux/); # "quux or quuux"
411
412           This function is not exported by default.
413

EXPORT

415       By default, all of the functions documented above are exported, except
416       "subtype" and "type" (prefer "declare" instead), "extends",
417       "dwim_type", "match_on_type"/"compile_match_on_type", "classifier", and
418       "english_list".
419
420       This module uses Exporter::Tiny; see the documentation of that module
421       for tips and tricks importing from Type::Utils.
422

BUGS

424       Please report any bugs to
425       <https://github.com/tobyink/p5-type-tiny/issues>.
426

SEE ALSO

428       Type::Tiny::Manual.
429
430       Type::Tiny, Type::Library, Types::Standard, Type::Coercion.
431
432       Type::Tiny::Class, Type::Tiny::Role, Type::Tiny::Duck,
433       Type::Tiny::Enum, Type::Tiny::Union.
434
435       Moose::Util::TypeConstraints, Mouse::Util::TypeConstraints.
436

AUTHOR

438       Toby Inkster <tobyink@cpan.org>.
439
441       This software is copyright (c) 2013-2014, 2017-2021 by Toby Inkster.
442
443       This is free software; you can redistribute it and/or modify it under
444       the same terms as the Perl 5 programming language system itself.
445

DISCLAIMER OF WARRANTIES

447       THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
448       WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
449       MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
450
451
452
453perl v5.34.0                      2021-09-13                    Type::Utils(3)
Impressum