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