5 Moose::Manual::Types - Moose's type system
9 Moose provides its own type system for attributes. You can also use
10 these types to validate method parameters with the help of a MooseX
13 Moose's type system is based on a combination of Perl 5's own
14 I<implicit> types and some Perl 6 concepts. You can easily create your
15 own subtypes with custom constraints, making it easy to express any
18 Types have names, and you can re-use them by name, making it easy to
19 share types throughout a large application.
21 Let us be clear that is not a "real" type system. Moose does not
22 magically make Perl start associating types with variables. This is
23 just an advanced parameter checking system which allows you to
24 associate a name with a constraint.
26 That said, it's still pretty damn useful, and we think it's one of the
27 things that makes Moose both fun and powerful. Taking advantage of the
28 type system makes it much easier to ensure that you are getting valid
29 data, and it also contributes greatly to code maintainability.
33 The basic Moose type hierarchy looks like this
58 In practice, the only difference between C<Any> and C<Item> is
59 conceptual. C<Item> is used as the top-level type in the hierarchy.
61 The rest of these types correspond to existing Perl concepts. For
62 example, a C<Num> is anything that Perl thinks looks like a number. An
63 C<Object> is a blessed reference, etc.
65 The types followed by "[`a]" can be parameterized. So instead of just
66 plain C<ArrayRef> we can say that we want C<ArrayRef[Int]> instead. We
67 can even do something like C<HashRef[ArrayRef[Str]]>.
69 The C<Maybe[`a]> type deserves a special mention. Used by itself, it
70 doesn't really mean anything (and is equivalent to C<Item>). When it
71 is parameterized, it means that the value is either C<undef> or the
72 parameterized type. So C<Maybe[Int]> means an integer or C<undef>
74 For more details on the type hierarchy, see
75 L<Moose::Util::TypeConstraints>.
77 =head1 WHAT IS A TYPE?
79 It's important to realize that types are not classes (or
80 packages). Types are just objects (L<Moose::Meta::TypeConstraint>
81 objects, to be exact) with a name and a constraint. Moose maintains a
82 global type registry that lets it convert names like C<Num> into the
85 However, class names I<can be> type names. When you define a new class
86 using Moose, it defines an associated type name behind the scenes:
92 Now you can use C<'MyApp::User'> as a type name:
99 However, for non-Moose classes there's no magic. You may have to
100 explicitly declare the class type. This is a bit muddled because Moose
101 assumes that any unknown type name passed as the C<isa> value for an
102 attribute is a class. So this works:
104 has 'birth_date' => (
109 In general, when Moose is presented with an unknown name, it assumes
110 that the name is a class:
112 subtype 'ModernDateTime'
114 => where { $_->year() >= 1980 }
115 => message { 'The date you provided is not modern enough' };
117 has 'valid_dates' => (
119 isa => 'ArrayRef[DateTime]',
122 Moose will assume that C<DateTime> is a class name in both of these
127 Moose uses subtypes in its built-in hierarchy. C<Int> is a child of
130 A subtype is defined in terms of a parent type and a constraint. Any
131 constraints defined by the parent(s) will be checked first, and then
132 the the subtype's. A value must pass I<all> of these checks to be
133 valid for the subtype.
135 Typically, a subtype takes the parent's constraint and makes it more
138 A subtype can also define its own constraint failure message. This
139 lets you do things like have an error "The value you provided (20),
140 was not a valid rating, which must be a number from 1-10." This is
141 much friendlier than the default error, which just says that the value
142 failed a validation check for the type.
144 Here's a simple (and useful) subtype example:
146 subtype 'PositiveInt'
149 => message { "The number you provided, $_, was not a positive number" }
151 Note that the sugar functions for working with types are all exported
152 by L<Moose::Util::TypeConstraints>.
154 =head2 Creating a new type (that isn't a subtype)
156 You can also create new top-level types:
158 type 'FourCharacters' => where { defined $_ && length $_ == 4 };
160 In practice, this example is more or less the same as subtyping
161 C<Str>, except you have to check definedness yourself.
163 It's hard to find a case where you wouldn't want to subtype a very
164 broad type like C<Defined>, C<Ref> or C<Object>.
166 Defining a new top-level type is conceptually the same as subtyping
171 Type names are global throughout the current Perl
172 interpreter. Internally, Moose maps names to type objects via a
173 L<registry|Moose::Meta::TypeConstraint::Registry>.
175 If you have multiple apps or libraries all using Moose in the same
176 process, you could have problems with collisions. We recommend that
177 you prefix names with some sort of namespace indicator to prevent
178 these sorts of collisions.
180 For example, instead of calling a type "PositiveInt", call it
181 "MyApp::Type::PositiveInt" or "MyApp::Types::PositiveInt" - you may
182 find it easiest to centralize these definitions in a lib/MyApp/Types.pm
183 so the other classes in your application can simply do "use MyApp::Types"
184 and assume that all relevant types have now been defined.
186 The L<MooseX::Types> module provides namespaced types as functions so that
187 you can import the names into packages and use them as barewords - i.e.
189 has 'foo' => (isa => 'MyApp::Types::PositiveInt');
193 has 'foo' => (isa => PositiveInt);
197 One of the most powerful features of Moose's type system is its
198 coercions. A coercion is a way to convert from one type to another.
200 subtype 'ArrayRefOfInts'
201 => as 'ArrayRef[Int]';
203 coerce 'ArrayRefOfInts'
207 You'll note that we had to create a subtype rather than coercing
208 C<ArrayRef[Int]> directly. This is just a quirk of how Moose
211 Coercions, like type names, are global. This is I<another> reason why
212 it is good to namespace your types. Moose will I<never> try to coerce
213 a value unless you explicitly ask for it. This is done by setting the
214 C<coerce> attribute option to a true value:
220 isa => 'ArrayRefOfInts',
224 Foo->new( sizes => 42 );
226 This code example will do the right thing, and the newly created
227 object will have C<[ 42 ]> as its C<sizes> attribute.
231 Deep coercion is the coercion of type parameters for parameterized
232 types. Let's take these types as an example:
236 => where { /[a-f0-9]/i };
244 isa => 'ArrayRef[Int]',
248 If we try passing an array reference of hex numbers for the C<sizes>
249 attribute, Moose will not do any coercion.
251 However, you can define a set of subtypes to enable coercion between
252 two parameterized types.
254 subtype 'ArrayRefOfHexNums'
255 => as 'ArrayRef[HexNum]';
257 subtype 'ArrayRefOfInts'
258 => as 'ArrayRef[Int]';
260 coerce 'ArrayRefOfInts'
261 => from 'ArrayRefOfHexNums'
262 => via { [ map { hex } @{$_} ] };
264 Foo->new( sizes => [ 'a1', 'ff', '22' ] );
266 Now Moose will coerce the hex numbers to integers.
268 However, Moose does not attempt to chain coercions, so it will not
269 coerce a single hex number. To do that, we need to define a separate
272 coerce 'ArrayRefOfInts'
274 => via { [ hex $_ ] };
276 Yes, this can all get verbose, but coercion is tricky magic, and we
277 think it's best to make it explicit.
281 Moose allows you to say that an attribute can be of two or more
282 disparate types. For example, we might allow an C<Object> or
287 isa => 'Object | FileHandle',
290 Moose actually parses that string and recognizes that you are creating
291 a type union. The C<output> attribute will accept any sort of object,
292 as well as an unblessed file handle. It is up to you to do the right
293 thing for each of them in your code.
295 Whenever you use a type union, you should consider whether or not
296 coercion might be a better answer.
298 For our example above, we might want to be more specific, and insist
299 that output be an object with a C<print> method:
303 => where { $_->can('print') };
305 We can coerce file handles to an object that satisfies this condition
306 with a simple wrapper class:
319 my $fh = $self->handle();
324 Now we can define a coercion from C<FileHandle> to our wrapper class:
328 => via { FHWrapper->new( handle => $_ ) };
336 This pattern of using a coercion instead of a type union will help
337 make your class internals simpler.
339 =head1 TYPE CREATION HELPERS
341 The L<Moose::Util::TypeConstraints> module exports a number of helper
342 functions for creating specific kinds of types. These include
343 C<class_type>, C<role_type>, and C<maybe_type>. See the docs for
346 One helper worth noting is C<enum>, which allows you to create a
347 subtype of C<Str> that only allows the specified values:
349 enum 'RGB' => qw( red green blue );
351 This creates a type named C<RGB>
353 =head1 ANONYMOUS TYPES
355 All of the type creation functions return a type object. This type
356 object can be used wherever you would use a type name, as a parent
357 type, or as the value for an attribute's C<isa> option:
361 isa => subtype 'Int' => where { $_ > 0 },
364 This is handy when you want to create a one-off type and don't want to
365 "pollute" the global namespace registry.
367 =head1 VALIDATING METHOD PARAMETERS
369 Moose does not provide any means of validating method
370 parameters. However, there are several MooseX extensions on CPAN which
373 The simplest and least sugary is L<MooseX::Params::Validate>. This
374 lets you validate a set of named parameters using Moose types:
377 use MooseX::Params::Validate;
381 my %params = validated_hash(
383 bar => { isa => 'Str', default => 'Moose' },
388 L<MooseX::Params::Validate> also supports coercions.
390 There are several more powerful extensions that support method
391 parameter validation using Moose types, including
392 L<MooseX::Method::Signatures>, which gives you a full-blown C<method>
395 method morning (Str $name) {
396 $self->say("Good morning ${name}!");
399 =head1 LOAD ORDER ISSUES
401 Because Moose types are defined at runtime, you may run into load
402 order problems. In particular, you may want to use a class's type
403 constraint before that type has been defined.
405 We have several recommendations for ameliorating this problem. First,
406 define I<all> of your custom types in one module,
407 C<MyApp::Types>. Second, load this module in all of your other
410 If you are still having load order problems, you can make use of the
411 C<find_type_constraint> function exported by
412 L<Moose::Util::TypeConstraints>:
414 class_type('MyApp::User')
415 unless find_type_constraint('MyApp::User') || ;
417 This sort of "find or create" logic is simple to write, and will let
418 you work around load order issues.
422 Dave Rolsky E<lt>autarch@urth.orgE<gt>
424 =head1 COPYRIGHT AND LICENSE
426 Copyright 2009 by Infinity Interactive, Inc.
428 L<http://www.iinteractive.com>
430 This library is free software; you can redistribute it and/or modify
431 it under the same terms as Perl itself.