Make a bunch of example attributes read-only
[gitmo/Moose.git] / lib / Moose / Manual / Types.pod
CommitLineData
ecd7cc3e 1=pod
2
3=head1 NAME
4
d67ce58f 5Moose::Manual::Types - Moose's type system
ecd7cc3e 6
7=head1 TYPES IN PERL?
8
0c551c67 9Moose provides its own type system for attributes. You can also use
10these types to validate method parameters with the help of a MooseX
11module.
ecd7cc3e 12
13Moose's type system is based on a combination of Perl 5's own
0c551c67 14I<implicit> types and some Perl 6 concepts. You can easily create your
15own subtypes with custom constraints, making it easy to express any
16sort of validation.
ecd7cc3e 17
0c551c67 18Types have names, and you can re-use them by name, making it easy to
ecd7cc3e 19share types throughout a large application.
20
21Let us be clear that is not a "real" type system. Moose does not
0c551c67 22magically make Perl start associating types with variables. This is
23just an advanced parameter checking system which allows you to
24associate a name with a constraint.
ecd7cc3e 25
26That said, it's still pretty damn useful, and we think it's one of the
27things that makes Moose both fun and powerful. Taking advantage of the
28type system makes it much easier to ensure that you are getting valid
29data, and it also contributes greatly to code maintainability.
30
31=head1 THE TYPES
32
33The basic Moose type hierarchy looks like this
34
35 Any
36 Item
37 Bool
38 Maybe[`a]
39 Undef
40 Defined
41 Value
42 Num
43 Int
44 Str
45 ClassName
7612cc01 46 RoleName
ecd7cc3e 47 Ref
48 ScalarRef
49 ArrayRef[`a]
50 HashRef[`a]
51 CodeRef
52 RegexpRef
53 GlobRef
54 FileHandle
55 Object
56 Role
57
58In practice, the only difference between C<Any> and C<Item> is
59conceptual. C<Item> is used as the top-level type in the hierarchy.
60
61The rest of these types correspond to existing Perl concepts. For
62example, a C<Num> is anything that Perl thinks looks like a number. An
63C<Object> is a blessed reference, etc.
64
65The types followed by "[`a]" can be parameterized. So instead of just
66plain C<ArrayRef> we can say that we want C<ArrayRef[Int]> instead. We
67can even do something like C<HashRef[ArrayRef[Str]]>.
68
69The C<Maybe[`a]> type deserves a special mention. Used by itself, it
70doesn't really mean anything (and is equivalent to C<Item>). When it
71is parameterized, it means that the value is either C<undef> or the
72parameterized type. So C<Maybe[Int]> means an integer or C<undef>
73
74For more details on the type hierarchy, see
75L<Moose::Util::TypeConstraints>.
76
77=head1 WHAT IS A TYPE?
78
79It's important to realize that types are not classes (or
80packages). Types are just objects (L<Moose::Meta::TypeConstraint>
0c551c67 81objects, to be exact) with a name and a constraint. Moose maintains a
6549b0d1 82global type registry that lets it convert names like C<Num> into the
0c551c67 83appropriate object.
ecd7cc3e 84
85However, class names I<can be> type names. When you define a new class
86using Moose, it defines an associated type name behind the scenes:
87
88 package MyApp::User;
89
90 use Moose;
91
92Now you can use C<'MyApp::User'> as a type name:
93
94 has creator => (
95 is => 'rw',
96 isa => 'MyApp::User',
97 );
98
99However, for non-Moose classes there's no magic. You may have to
100explicitly declare the class type. This is a bit muddled because Moose
101assumes that any unknown type name passed as the C<isa> value for an
102attribute is a class. So this works:
103
104 has 'birth_date' => (
105 is => 'rw',
106 isa => 'DateTime',
107 );
108
109In general, when Moose is presented with an unknown name, it assumes
110that the name is a class:
111
112 subtype 'ModernDateTime'
113 => as 'DateTime'
114 => where { $_->year() >= 1980 }
115 => message { 'The date you provided is not modern enough' };
116
117 has 'valid_dates' => (
118 is => 'ro',
119 isa => 'ArrayRef[DateTime]',
120 );
121
0c39debe 122Moose will assume that C<DateTime> is a class name in both of these
0c551c67 123instances.
ecd7cc3e 124
125=head1 SUBTYPES
126
127Moose uses subtypes in its built-in hierarchy. C<Int> is a child of
128C<Num> for example.
129
130A subtype is defined in terms of a parent type and a constraint. Any
131constraints defined by the parent(s) will be checked first, and then
0c39debe 132the the subtype's. A value must pass I<all> of these checks to be
0c551c67 133valid for the subtype.
ecd7cc3e 134
0c551c67 135Typically, a subtype takes the parent's constraint and makes it more
ecd7cc3e 136specific.
137
138A subtype can also define its own constraint failure message. This
139lets you do things like have an error "The value you provided (20),
140was not a valid rating, which must be a number from 1-10." This is
141much friendlier than the default error, which just says that the value
142failed a validation check for the type.
143
144Here's a simple (and useful) subtype example:
145
146 subtype 'PositiveInt'
147 => as 'Int'
148 => where { $_ > 0 }
149 => message { "The number you provided, $_, was not a positive number" }
150
151Note that the sugar functions for working with types are all exported
152by L<Moose::Util::TypeConstraints>.
153
d67ce58f 154=head2 Creating a new type (that isn't a subtype)
ecd7cc3e 155
156You can also create new top-level types:
157
158 type 'FourCharacters' => where { defined $_ && length $_ == 4 };
159
0c551c67 160In practice, this example is more or less the same as subtyping
636f25f3 161C<Str>, except you have to check definedness yourself.
ecd7cc3e 162
163It's hard to find a case where you wouldn't want to subtype a very
164broad type like C<Defined>, C<Ref> or C<Object>.
165
0c551c67 166Defining a new top-level type is conceptually the same as subtyping
167C<Item>.
ecd7cc3e 168
169=head1 TYPE NAMES
170
171Type names are global throughout the current Perl
0c551c67 172interpreter. Internally, Moose maps names to type objects via a
173L<registry|Moose::Meta::TypeConstraint::Registry>.
ecd7cc3e 174
175If you have multiple apps or libraries all using Moose in the same
176process, you could have problems with collisions. We recommend that
177you prefix names with some sort of namespace indicator to prevent
178these sorts of collisions.
179
180For example, instead of calling a type "PositiveInt", call it
181"MyApp.Type.PositiveInt".
182
0c551c67 183Type names are just strings. We recommend that you I<do not> use "::"
184as a separator in type names. This can be very confusing, because
185class names are I<also> valid type names! Using something else, like a
186period, makes it clear that "MyApp::User" is a class and
187"MyApp.Type.PositiveInt" is a Moose type defined by your application.
ecd7cc3e 188
0c39debe 189The L<MooseX::Types> module lets you create bareword aliases to longer
0c551c67 190names and also automatically namespaces all the types you define.
ecd7cc3e 191
192=head1 COERCION
193
194One of the most powerful features of Moose's type system is its
0c551c67 195coercions. A coercion is a way to convert from one type to another.
ecd7cc3e 196
197 subtype 'ArrayRefOfInts'
198 => as 'ArrayRef[Int]';
199
200 coerce 'ArrayRefOfInts'
201 => from 'Int'
202 => via { [ $_ ] };
203
204You'll note that we had to create a subtype rather than coercing
205C<ArrayRef[Int]> directly. This is just a quirk of how Moose
206works.
207
208Coercions, like type names, are global. This is I<another> reason why
209it is good to namespace your types. Moose will I<never> try to coerce
210a value unless you explicitly ask for it. This is done by setting the
16fb3624 211C<coerce> attribute option to a true value:
ecd7cc3e 212
213 package Foo;
214
215 has 'sizes' => (
216 is => 'rw',
217 isa => 'ArrayRefOfInts',
218 coerce => 1,
219 );
220
221 Foo->new( sizes => 42 );
222
223This code example will do the right thing, and the newly created
224object will have C<[ 42 ]> as its C<sizes> attribute.
225
d67ce58f 226=head2 Deep coercion
ecd7cc3e 227
228Deep coercion is the coercion of type parameters for parameterized
229types. Let's take these types as an example:
230
231 subtype 'HexNum'
232 => as 'Str'
233 => where { /[a-f0-9]/i };
234
235 coerce 'Int'
236 => from 'HexNum'
237 => via { hex $_ };
238
239 has 'sizes' => (
240 is => 'rw',
241 isa => 'ArrayRef[Int]',
242 coerce => 1,
243 );
244
245If we try passing an array reference of hex numbers for the C<sizes>
0c551c67 246attribute, Moose will not do any coercion.
ecd7cc3e 247
0c551c67 248However, you can define a set of subtypes to enable coercion between
249two parameterized types.
ecd7cc3e 250
251 subtype 'ArrayRefOfHexNums'
252 => as 'ArrayRef[HexNum]';
253
254 subtype 'ArrayRefOfInts'
255 => as 'ArrayRef[Int]';
256
257 coerce 'ArrayRefOfInts'
258 => from 'ArrayRefOfHexNums'
259 => via { [ map { hex } @{$_} ] };
260
261 Foo->new( sizes => [ 'a1', 'ff', '22' ] );
262
263Now Moose will coerce the hex numbers to integers.
264
0c551c67 265However, Moose does not attempt to chain coercions, so it will not
266coerce a single hex number. To do that, we need to define a separate
267coercion:
ecd7cc3e 268
269 coerce 'ArrayRefOfInts'
270 => from 'HexNum'
271 => via { [ hex $_ ] };
272
273Yes, this can all get verbose, but coercion is tricky magic, and we
0c551c67 274think it's best to make it explicit.
ecd7cc3e 275
276=head1 TYPE UNIONS
277
278Moose allows you to say that an attribute can be of two or more
279disparate types. For example, we might allow an C<Object> or
280C<FileHandle>:
281
282 has 'output' => (
283 is => 'rw',
284 isa => 'Object | FileHandle',
285 );
286
287Moose actually parses that string and recognizes that you are creating
288a type union. The C<output> attribute will accept any sort of object,
289as well as an unblessed file handle. It is up to you to do the right
290thing for each of them in your code.
291
0c551c67 292Whenever you use a type union, you should consider whether or not
293coercion might be a better answer.
ecd7cc3e 294
295For our example above, we might want to be more specific, and insist
296that output be an object with a C<print> method:
297
298 subtype 'CanPrint'
299 => as 'Object'
300 => where { $_->can('print') };
301
302We can coerce file handles to an object that satisfies this condition
303with a simple wrapper class:
304
305 package FHWrapper;
306
307 use Moose;
308
309 has 'handle' => (
310 is => 'ro',
311 isa => 'FileHandle',
312 );
313
314 sub print {
315 my $self = shift;
316 my $fh = $self->handle();
317
318 print $fh @_;
319 }
320
321Now we can define a coercion from C<FileHandle> to our wrapper class:
322
0c551c67 323 coerce 'CanPrint'
ecd7cc3e 324 => from 'FileHandle'
325 => via { FHWrapper->new( handle => $_ ) };
326
327 has 'output' => (
328 is => 'rw',
329 isa => 'CanPrint',
330 coerce => 1,
331 );
332
0c551c67 333This pattern of using a coercion instead of a type union will help
334make your class internals simpler.
ecd7cc3e 335
336=head1 TYPE CREATION HELPERS
337
338The L<Moose::Util::TypeConstraints> module exports a number of helper
339functions for creating specific kinds of types. These include
340C<class_type>, C<role_type>, and C<maybe_type>. See the docs for
341details.
342
343One helper worth noting is C<enum>, which allows you to create a
344subtype of C<Str> that only allows the specified values:
345
346 enum 'RGB' => qw( red green blue );
347
348This creates a type named C<RGB>
349
350=head1 ANONYMOUS TYPES
351
352All of the type creation functions return a type object. This type
353object can be used wherever you would use a type name, as a parent
16fb3624 354type, or as the value for an attribute's C<isa> option:
ecd7cc3e 355
356 has 'size' => (
357 is => 'rw',
358 isa => subtype 'Int' => where { $_ > 0 },
359 );
360
361This is handy when you want to create a one-off type and don't want to
362"pollute" the global namespace registry.
363
364=head1 VALIDATING METHOD PARAMETERS
365
366Moose does not provide any means of validating method
367parameters. However, there are several MooseX extensions on CPAN which
368let you do this.
369
0c39debe 370The simplest and least sugary is L<MooseX::Params::Validate>. This
ecd7cc3e 371lets you validate a set of named parameters using Moose types:
372
373 use Moose;
374 use MooseX::Params::Validate;
375
376 sub foo {
377 my $self = shift;
0c551c67 378 my %params = validated_hash(
ecd7cc3e 379 \@_,
380 bar => { isa => 'Str', default => 'Moose' },
381 );
382 ...
383 }
384
0c39debe 385L<MooseX::Params::Validate> also supports coercions.
ecd7cc3e 386
387There are several more powerful extensions that support method
388parameter validation using Moose types, including
0c39debe 389L<MooseX::Method::Signatures>, which gives you a full-blown C<method>
ecd7cc3e 390keyword.
391
392 method morning (Str $name) {
393 $self->say("Good morning ${name}!");
394 }
395
ca680d1f 396=head1 LOAD ORDER ISSUES
397
0c551c67 398Because Moose types are defined at runtime, you may run into load
399order problems. In particular, you may want to use a class's type
400constraint before that type has been defined.
ca680d1f 401
0c551c67 402We have several recommendations for ameliorating this problem. First,
403define I<all> of your custom types in one module,
404C<MyApp::Types>. Second, load this module in all of your other
405modules.
ca680d1f 406
407If you are still having load order problems, you can make use of the
408C<find_type_constraint> function exported by
409L<Moose::Util::TypeConstraints>:
410
0c551c67 411 class_type('MyApp::User')
412 unless find_type_constraint('MyApp::User') || ;
ca680d1f 413
414This sort of "find or create" logic is simple to write, and will let
415you work around load order issues.
416
ecd7cc3e 417=head1 AUTHOR
418
419Dave Rolsky E<lt>autarch@urth.orgE<gt>
420
421=head1 COPYRIGHT AND LICENSE
422
2840a3b2 423Copyright 2009 by Infinity Interactive, Inc.
ecd7cc3e 424
425L<http://www.iinteractive.com>
426
427This library is free software; you can redistribute it and/or modify
428it under the same terms as Perl itself.
429
430=cut