1MooseX::Types(3pm) User Contributed Perl Documentation MooseX::Types(3pm)
2
3
4
6 MooseX::Types - Organise your Moose types in libraries
7
9 version 0.50
10
12 Library Definition
13 package MyLibrary;
14
15 # predeclare our own types
16 use MooseX::Types -declare => [
17 qw(
18 PositiveInt
19 NegativeInt
20 ArrayRefOfPositiveInt
21 ArrayRefOfAtLeastThreeNegativeInts
22 LotsOfInnerConstraints
23 StrOrArrayRef
24 MyDateTime
25 )
26 ];
27
28 # import builtin types
29 use MooseX::Types::Moose qw/Int HashRef/;
30
31 # type definition.
32 subtype PositiveInt,
33 as Int,
34 where { $_ > 0 },
35 message { "Int is not larger than 0" };
36
37 subtype NegativeInt,
38 as Int,
39 where { $_ < 0 },
40 message { "Int is not smaller than 0" };
41
42 # type coercion
43 coerce PositiveInt,
44 from Int,
45 via { 1 };
46
47 # with parameterized constraints.
48
49 subtype ArrayRefOfPositiveInt,
50 as ArrayRef[PositiveInt];
51
52 subtype ArrayRefOfAtLeastThreeNegativeInts,
53 as ArrayRef[NegativeInt],
54 where { scalar(@$_) > 2 };
55
56 subtype LotsOfInnerConstraints,
57 as ArrayRef[ArrayRef[HashRef[Int]]];
58
59 # with TypeConstraint Unions
60
61 subtype StrOrArrayRef,
62 as Str|ArrayRef;
63
64 # class types
65
66 class_type 'DateTime';
67
68 # or better
69
70 class_type MyDateTime, { class => 'DateTime' };
71
72 coerce MyDateTime,
73 from HashRef,
74 via { DateTime->new(%$_) };
75
76 1;
77
78 Usage
79 package Foo;
80 use Moose;
81 use MyLibrary qw( PositiveInt NegativeInt );
82
83 # use the exported constants as type names
84 has 'bar',
85 isa => PositiveInt,
86 is => 'rw';
87 has 'baz',
88 isa => NegativeInt,
89 is => 'rw';
90
91 sub quux {
92 my ($self, $value);
93
94 # test the value
95 print "positive\n" if is_PositiveInt($value);
96 print "negative\n" if is_NegativeInt($value);
97
98 # coerce the value, NegativeInt doesn't have a coercion
99 # helper, since it didn't define any coercions.
100 $value = to_PositiveInt($value) or die "Cannot coerce";
101 }
102
103 1;
104
106 The type system provided by Moose effectively makes all of its builtin
107 type global, as are any types you declare with Moose. This means that
108 every module that declares a type named "PositiveInt" is sharing the
109 same type object. This can be a problem when different parts of the
110 code base want to use the same name for different things.
111
112 This package lets you declare types using short names, but behind the
113 scenes it namespaces all your type declarations, effectively prevent
114 name clashes between packages.
115
116 This is done by creating a type library module like "MyApp::Types" and
117 then importing types from that module into other modules.
118
119 As a side effect, the declaration mechanism allows you to write type
120 names as barewords (really function calls), which catches typos in
121 names at compile time rather than run time.
122
123 This module also provides some helper functions for using Moose types
124 outside of attribute declarations.
125
126 If you mix string-based names with types created by this module, it
127 will warn, with a few exceptions. If you are declaring a "class_type()"
128 or "role_type()" within your type library, or if you use a fully
129 qualified name like "MyApp::Foo".
130
132 A MooseX::Types is just a normal Perl module. Unlike Moose itself, it
133 does not install "use strict" and "use warnings" in your class by
134 default, so this is up to you.
135
136 The only thing a library is required to do is
137
138 use MooseX::Types -declare => \@types;
139
140 with @types being a list of types you wish to define in this library.
141 This line will install a proper base class in your package as well as
142 the full set of handlers for your declared types. It will then hand
143 control over to Moose::Util::TypeConstraints' "import" method to export
144 the functions you will need to declare your types.
145
146 If you want to use Moose' built-in types (e.g. for subtyping) you will
147 want to
148
149 use MooseX::Types::Moose @types;
150
151 to import the helpers from the shipped MooseX::Types::Moose library
152 which can export all types that come with Moose.
153
154 You will have to define coercions for your types or your library won't
155 export a "to_$type" coercion helper for it.
156
157 Note that you currently cannot define types containing "::", since
158 exporting would be a problem.
159
160 You also don't need to use "warnings" and "strict", since the
161 definition of a library automatically exports those.
162
164 You can import the "type helpers" of a library by "use"ing it with a
165 list of types to import as arguments. If you want all of them, use the
166 ":all" tag. For example:
167
168 use MyLibrary ':all';
169 use MyOtherLibrary qw( TypeA TypeB );
170
171 MooseX::Types comes with a library of Moose' built-in types called
172 MooseX::Types::Moose.
173
174 The exporting mechanism is, since version 0.5, implemented via a
175 wrapper around Sub::Exporter. This means you can do something like
176 this:
177
178 use MyLibrary TypeA => { -as => 'MyTypeA' },
179 TypeB => { -as => 'MyTypeB' };
180
182 $type
183 A constant with the name of your type. It contains the type's fully
184 qualified name. Takes no value, as all constants.
185
186 is_$type
187 This handler takes a value and tests if it is a valid value for this
188 $type. It will return true or false.
189
190 to_$type
191 A handler that will take a value and coerce it into the $type. It will
192 return a false value if the type could not be coerced.
193
194 Important Note: This handler will only be exported for types that can
195 do type coercion. This has the advantage that a coercion to a type that
196 has not defined any coercions will lead to a compile-time error.
197
199 You can define your own wrapper subclasses to manipulate the behaviour
200 of a set of library exports. Here is an example:
201
202 package MyWrapper;
203 use strict;
204 use MRO::Compat;
205 use base 'MooseX::Types::Wrapper';
206
207 sub coercion_export_generator {
208 my $class = shift;
209 my $code = $class->next::method(@_);
210 return sub {
211 my $value = $code->(@_);
212 warn "Coercion returned undef!"
213 unless defined $value;
214 return $value;
215 };
216 }
217
218 1;
219
220 This class wraps the coercion generator (e.g., "to_Int()") and warns if
221 a coercion returned an undefined value. You can wrap any library with
222 this:
223
224 package Foo;
225 use strict;
226 use MyWrapper MyLibrary => [qw( Foo Bar )],
227 Moose => [qw( Str Int )];
228
229 ...
230 1;
231
232 The "Moose" library name is a special shortcut for
233 MooseX::Types::Moose.
234
235 Generator methods you can overload
236 type_export_generator( $short, $full )
237 Creates a closure returning the type's Moose::Meta::TypeConstraint
238 object.
239
240 check_export_generator( $short, $full, $undef_message )
241 This creates the closure used to test if a value is valid for this
242 type.
243
244 coercion_export_generator( $short, $full, $undef_message )
245 This is the closure that's doing coercions.
246
247 Provided Parameters
248 $short
249 The short, exported name of the type.
250
251 $full
252 The fully qualified name of this type as Moose knows it.
253
254 $undef_message
255 A message that will be thrown when type functionality is used but
256 the type does not yet exist.
257
259 As of version 0.08, Moose::Types has experimental support for Recursive
260 subtypes. This will allow:
261
262 subtype Tree() => as HashRef[Str|Tree];
263
264 Which validates things like:
265
266 {key=>'value'};
267 {key=>{subkey1=>'value', subkey2=>'value'}}
268
269 And so on. This feature is new and there may be lurking bugs so don't
270 be afraid to hunt me down with patches and test cases if you have
271 trouble.
272
274 MooseX::Types uses MooseX::Types::TypeDecorator to do some overloading
275 which generally allows you to easily create union types:
276
277 subtype StrOrArrayRef,
278 as Str|ArrayRef;
279
280 As with parameterized constraints, this overloading extends to modules
281 using the types you define in a type library.
282
283 use Moose;
284 use MooseX::Types::Moose qw(HashRef Int);
285
286 has 'attr' => ( isa => HashRef | Int );
287
288 And everything should just work as you'd think.
289
291 import
292 Installs the MooseX::Types::Base class into the caller and exports
293 types according to the specification described in "LIBRARY DEFINITION".
294 This will continue to Moose::Util::TypeConstraints' "import" method to
295 export helper functions you will need to declare your types.
296
297 type_export_generator
298 Generate a type export, e.g. "Int()". This will return either a
299 Moose::Meta::TypeConstraint object, or alternatively a
300 MooseX::Types::UndefinedType object if the type was not yet defined.
301
302 create_arged_type_constraint ($name, @args)
303 Given a String $name with @args find the matching type constraint and
304 parameterize it with @args.
305
306 create_base_type_constraint ($name)
307 Given a String $name, find the matching type constraint.
308
309 create_type_decorator ($type_constraint)
310 Given a $type_constraint, return a lightweight
311 MooseX::Types::TypeDecorator instance.
312
313 coercion_export_generator
314 This generates a coercion handler function, e.g. "to_Int($value)".
315
316 check_export_generator
317 Generates a constraint check closure, e.g. "is_Int($value)".
318
320 The following are lists of gotchas and their workarounds for developers
321 coming from the standard string based type constraint names
322
323 Uniqueness
324 A library makes the types quasi-unique by prefixing their names with
325 (by default) the library package name. If you're only using the type
326 handler functions provided by MooseX::Types, you shouldn't ever have to
327 use a type's actual full name.
328
329 Argument separation ('=>' versus ',')
330 The perlop manpage has this to say about the '=>' operator: "The =>
331 operator is a synonym for the comma, but forces any word (consisting
332 entirely of word characters) to its left to be interpreted as a string
333 (as of 5.001). This includes words that might otherwise be considered a
334 constant or function call."
335
336 Due to this stringification, the following will NOT work as you might
337 think:
338
339 subtype StrOrArrayRef => as Str | ArrayRef;
340
341 The "StrOrArrayRef" type will have its stringification activated --
342 this causes the subtype to not be created. Since the bareword type
343 constraints are not strings you really should not try to treat them
344 that way. You will have to use the ',' operator instead. The authors
345 of this package realize that all the Moose documentation and examples
346 nearly uniformly use the '=>' version of the comma operator and this
347 could be an issue if you are converting code.
348
349 Patches welcome for discussion.
350
351 Compatibility with Sub::Exporter
352 If you want to use Sub::Exporter with a Type Library, you need to make
353 sure you export all the type constraints declared AS WELL AS any
354 additional export targets. For example if you do:
355
356 package TypeAndSubExporter;
357
358 use MooseX::Types::Moose qw(Str);
359 use MooseX::Types -declare => [qw(MyStr)];
360 use Sub::Exporter -setup => { exports => [qw(something)] };
361
362 subtype MyStr, as Str;
363
364 sub something {
365 return 1;
366 }
367
368 # then in another module ...
369
370 package Foo;
371 use TypeAndSubExporter qw(MyStr);
372
373 You'll get a ""MyStr" is not exported by the TypeAndSubExporter module"
374 error. It can be worked around by:
375
376 - use Sub::Exporter -setup => { exports => [ qw(something) ] };
377 + use Sub::Exporter -setup => { exports => [ qw(something MyStr) ] };
378
379 This is a workaround and I am exploring how to make these modules work
380 better together. I realize this workaround will lead a lot of
381 duplication in your export declarations and will be onerous for large
382 type libraries. Patches and detailed test cases welcome. See the tests
383 directory for a start on this.
384
386 You may want to combine a set of types for your application with other
387 type libraries, like MooseX::Types::Moose or
388 MooseX::Types::Common::String.
389
390 The MooseX::Types::Combine module provides a simple API for combining a
391 set of type libraries together.
392
394 Moose, Moose::Util::TypeConstraints, MooseX::Types::Moose,
395 Sub::Exporter
396
398 Many thanks to the "#moose" cabal on "irc.perl.org".
399
401 Bugs may be submitted through the RT bug tracker
402 <https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Types> (or
403 bug-MooseX-Types@rt.cpan.org <mailto:bug-MooseX-Types@rt.cpan.org>).
404
405 There is also a mailing list available for users of this distribution,
406 at <http://lists.perl.org/list/moose.html>.
407
408 There is also an irc channel available for users of this distribution,
409 at "#moose" on "irc.perl.org" <irc://irc.perl.org/#moose>.
410
412 Robert "phaylon" Sedlacek <rs@474.at>
413
415 • Karen Etheridge <ether@cpan.org>
416
417 • Dave Rolsky <autarch@urth.org>
418
419 • John Napiorkowski <jjnapiork@cpan.org>
420
421 • Robert 'phaylon' Sedlacek <phaylon@cpan.org>
422
423 • Rafael Kitover <rkitover@cpan.org>
424
425 • Florian Ragwitz <rafl@debian.org>
426
427 • Matt S Trout <mst@shadowcat.co.uk>
428
429 • Tomas Doran (t0m) <bobtfish@bobtfish.net>
430
431 • Jesse Luehrs <doy@tozt.net>
432
433 • Mark Fowler <mark@twoshortplanks.com>
434
435 • Hans Dieter Pearcey <hdp@weftsoar.net>
436
437 • Graham Knop <haarg@haarg.org>
438
439 • Paul Fenwick <pjf@perltraining.com.au>
440
441 • Kent Fredric <kentfredric@gmail.com>
442
443 • Justin Hunter <justin.d.hunter@gmail.com>
444
446 This software is copyright (c) 2007 by Robert "phaylon" Sedlacek.
447
448 This is free software; you can redistribute it and/or modify it under
449 the same terms as the Perl 5 programming language system itself.
450
451
452
453perl v5.34.0 2021-07-22 MooseX::Types(3pm)