1Moose::Manual::Types(3)User Contributed Perl DocumentatioMnoose::Manual::Types(3)
2
3
4

NAME

6       Moose::Manual::Types - Moose's type system
7

TYPES IN PERL?

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
11       module.
12
13       Moose's type system is based on a combination of Perl 5's own implicit
14       types and some Perl 6 concepts. You can easily create your own subtypes
15       with custom constraints, making it easy to express any sort of
16       validation.
17
18       Types have names, and you can re-use them by name, making it easy to
19       share types throughout a large application.
20
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.
25
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.
30

THE TYPES

32       The basic Moose type hierarchy looks like this
33
34         Any
35         Item
36             Bool
37             Maybe[`a]
38             Undef
39             Defined
40                 Value
41                     Str
42                       Num
43                           Int
44                       ClassName
45                       RoleName
46                 Ref
47                     ScalarRef[`a]
48                     ArrayRef[`a]
49                     HashRef[`a]
50                     CodeRef
51                     RegexpRef
52                     GlobRef
53                       FileHandle
54                     Object
55
56       In practice, the only difference between "Any" and "Item" is
57       conceptual. "Item" is used as the top-level type in the hierarchy.
58
59       The rest of these types correspond to existing Perl concepts.  In
60       particular:
61
62       "Bool" accepts 1 for true, and any value that perl treats as false for
63       false.
64       "Maybe[`a]" accepts either "`a" or "undef".
65       "Num" accepts anything that perl thinks looks like a number (see
66       "looks_like_number" in Scalar::Util).
67       "ClassName" and "RoleName" accept strings that are either the name of a
68       class or the name of a role. The class/role must be loaded beforehand
69       for this to succeed.
70       "FileHandle" accepts either an object of type IO::Handle or a builtin
71       perl filehandle (see "openhandle" in Scalar::Util).
72       "Object" accepts any blessed reference.
73
74       The types followed by "[`a]" can be parameterized. So instead of just
75       plain "ArrayRef" we can say that we want "ArrayRef[Int]" instead. We
76       can even do something like "HashRef[ArrayRef[Str]]".
77
78       The "Maybe[`a]" type deserves a special mention. Used by itself, it
79       doesn't really mean anything (and is equivalent to "Item"). When it is
80       parameterized, it means that the value is either "undef" or the
81       parameterized type. So "Maybe[Int]" means an integer or "undef".
82
83       For more details on the type hierarchy, see
84       Moose::Util::TypeConstraints.
85

WHAT IS A TYPE?

87       It's important to realize that types are not classes (or packages).
88       Types are just objects (Moose::Meta::TypeConstraint objects, to be
89       exact) with a name and a constraint. Moose maintains a global type
90       registry that lets it convert names like "Num" into the appropriate
91       object.
92
93       However, class names can be type names. When you define a new class
94       using Moose, it defines an associated type name behind the scenes:
95
96         package MyApp::User;
97
98         use Moose;
99
100       Now you can use 'MyApp::User' as a type name:
101
102         has creator => (
103             is  => 'ro',
104             isa => 'MyApp::User',
105         );
106
107       However, for non-Moose classes there's no magic. You may have to
108       explicitly declare the class type. This is a bit muddled because Moose
109       assumes that any unknown type name passed as the "isa" value for an
110       attribute is a class. So this works:
111
112         has 'birth_date' => (
113             is  => 'ro',
114             isa => 'DateTime',
115         );
116
117       In general, when Moose is presented with an unknown name, it assumes
118       that the name is a class:
119
120         subtype 'ModernDateTime'
121             => as 'DateTime'
122             => where { $_->year() >= 1980 }
123             => message { 'The date you provided is not modern enough' };
124
125         has 'valid_dates' => (
126             is  => 'ro',
127             isa => 'ArrayRef[DateTime]',
128         );
129
130       Moose will assume that "DateTime" is a class name in both of these
131       instances.
132

SUBTYPES

134       Moose uses subtypes in its built-in hierarchy. For example, "Int" is a
135       child of "Num".
136
137       A subtype is defined in terms of a parent type and a constraint. Any
138       constraints defined by the parent(s) will be checked first, followed by
139       constraints defined by the subtype. A value must pass all of these
140       checks to be valid for the subtype.
141
142       Typically, a subtype takes the parent's constraint and makes it more
143       specific.
144
145       A subtype can also define its own constraint failure message. This lets
146       you do things like have an error "The value you provided (20), was not
147       a valid rating, which must be a number from 1-10." This is much
148       friendlier than the default error, which just says that the value
149       failed a validation check for the type.
150
151       Here's a simple (and useful) subtype example:
152
153         subtype 'PositiveInt'
154             => as 'Int'
155             => where { $_ > 0 }
156             => message { "The number you provided, $_, was not a positive number" }
157
158       Note that the sugar functions for working with types are all exported
159       by Moose::Util::TypeConstraints.
160
161   Creating a new type (that isn't a subtype)
162       You can also create new top-level types:
163
164         type 'FourCharacters' => where { defined $_ && length $_ == 4 };
165
166       In practice, this example is more or less the same as subtyping "Str",
167       except you have to check definedness yourself.
168
169       It's hard to find a case where you wouldn't want to subtype a very
170       broad type like "Defined", "Ref" or "Object".
171
172       Defining a new top-level type is conceptually the same as subtyping
173       "Item".
174

TYPE NAMES

176       Type names are global throughout the current Perl interpreter.
177       Internally, Moose maps names to type objects via a registry.
178
179       If you have multiple apps or libraries all using Moose in the same
180       process, you could have problems with collisions. We recommend that you
181       prefix names with some sort of namespace indicator to prevent these
182       sorts of collisions.
183
184       For example, instead of calling a type "PositiveInt", call it
185       "MyApp::Type::PositiveInt" or "MyApp::Types::PositiveInt". We recommend
186       that you centralize all of these definitions in a single package,
187       "MyApp::Types", which can be loaded by other classes in your
188       application.
189
190       Once you're doing this, you should almost certainly look at the
191       MooseX::Types module. This module makes it easy to create a "type
192       library" module, which can export your types as perl constants.
193
194         has 'counter' => (is => 'rw', isa => PositiveInt);
195
196       This lets you use a short name rather than needing to fully qualify the
197       name everywhere. It also allows you to write easily create
198       parameterized types:
199
200         has 'counts' => (is => 'ro', isa => HashRef[PositiveInt]);
201
202       This module will check your names at compile time, and is generally
203       more robust than the string type parsing for complex cases.
204

COERCION

206       One of the most powerful features of Moose's type system is its
207       coercions. A coercion is a way to convert from one type to another.
208
209         subtype 'ArrayRefOfInts'
210             => as 'ArrayRef[Int]';
211
212         coerce 'ArrayRefOfInts'
213             => from 'Int'
214             => via { [ $_ ] };
215
216       You'll note that we had to create a subtype rather than coercing
217       "ArrayRef[Int]" directly. This is just a quirk of how Moose works.
218
219       Coercions, like type names, are global. This is another reason why it
220       is good to namespace your types. Moose will never try to coerce a value
221       unless you explicitly ask for it. This is done by setting the "coerce"
222       attribute option to a true value:
223
224         package Foo;
225
226         has 'sizes' => (
227             is     => 'ro',
228             isa    => 'ArrayRefOfInts',
229             coerce => 1,
230         );
231
232         Foo->new( sizes => 42 );
233
234       This code example will do the right thing, and the newly created object
235       will have "[ 42 ]" as its "sizes" attribute.
236
237   Deep coercion
238       Deep coercion is the coercion of type parameters for parameterized
239       types. Let's take these types as an example:
240
241         subtype 'HexNum'
242             => as 'Str'
243             => where { /[a-f0-9]/i };
244
245         coerce 'Int'
246             => from 'HexNum'
247             => via { hex $_ };
248
249         has 'sizes' => (
250             is     => 'ro',
251             isa    => 'ArrayRef[Int]',
252             coerce => 1,
253         );
254
255       If we try passing an array reference of hex numbers for the "sizes"
256       attribute, Moose will not do any coercion.
257
258       However, you can define a set of subtypes to enable coercion between
259       two parameterized types.
260
261         subtype 'ArrayRefOfHexNums'
262             => as 'ArrayRef[HexNum]';
263
264         subtype 'ArrayRefOfInts'
265             => as 'ArrayRef[Int]';
266
267         coerce 'ArrayRefOfInts'
268             => from 'ArrayRefOfHexNums'
269             => via { [ map { hex } @{$_} ] };
270
271         Foo->new( sizes => [ 'a1', 'ff', '22' ] );
272
273       Now Moose will coerce the hex numbers to integers.
274
275       However, Moose does not attempt to chain coercions, so it will not
276       coerce a single hex number. To do that, we need to define a separate
277       coercion:
278
279         coerce 'ArrayRefOfInts'
280             => from 'HexNum'
281             => via { [ hex $_ ] };
282
283       Yes, this can all get verbose, but coercion is tricky magic, and we
284       think it's best to make it explicit.
285

TYPE UNIONS

287       Moose allows you to say that an attribute can be of two or more
288       disparate types. For example, we might allow an "Object" or
289       "FileHandle":
290
291         has 'output' => (
292             is  => 'rw',
293             isa => 'Object | FileHandle',
294         );
295
296       Moose actually parses that string and recognizes that you are creating
297       a type union. The "output" attribute will accept any sort of object, as
298       well as an unblessed file handle. It is up to you to do the right thing
299       for each of them in your code.
300
301       Whenever you use a type union, you should consider whether or not
302       coercion might be a better answer.
303
304       For our example above, we might want to be more specific, and insist
305       that output be an object with a "print" method:
306
307         subtype 'CanPrint'
308             => as 'Object'
309             => where { $_->can('print') };
310
311       We can coerce file handles to an object that satisfies this condition
312       with a simple wrapper class:
313
314         package FHWrapper;
315
316         use Moose;
317
318         has 'handle' => (
319             is  => 'rw',
320             isa => 'FileHandle',
321         );
322
323         sub print {
324             my $self = shift;
325             my $fh   = $self->handle();
326
327             print $fh @_;
328         }
329
330       Now we can define a coercion from "FileHandle" to our wrapper class:
331
332         coerce 'CanPrint'
333             => from 'FileHandle'
334             => via { FHWrapper->new( handle => $_ ) };
335
336         has 'output' => (
337             is     => 'rw',
338             isa    => 'CanPrint',
339             coerce => 1,
340         );
341
342       This pattern of using a coercion instead of a type union will help make
343       your class internals simpler.
344

TYPE CREATION HELPERS

346       The Moose::Util::TypeConstraints module exports a number of helper
347       functions for creating specific kinds of types. These include
348       "class_type", "role_type", and "maybe_type". See the docs for details.
349
350       One helper worth noting is "enum", which allows you to create a subtype
351       of "Str" that only allows the specified values:
352
353         enum 'RGB' => qw( red green blue );
354
355       This creates a type named "RGB".
356

ANONYMOUS TYPES

358       All of the type creation functions return a type object. This type
359       object can be used wherever you would use a type name, as a parent
360       type, or as the value for an attribute's "isa" option:
361
362         has 'size' => (
363             is => 'ro',
364             isa => subtype('Int' => where { $_ > 0 }),
365         );
366
367       This is handy when you want to create a one-off type and don't want to
368       "pollute" the global namespace registry.
369

VALIDATING METHOD PARAMETERS

371       Moose does not provide any means of validating method parameters.
372       However, there are several MooseX extensions on CPAN which let you do
373       this.
374
375       The simplest and least sugary is MooseX::Params::Validate. This lets
376       you validate a set of named parameters using Moose types:
377
378         use Moose;
379         use MooseX::Params::Validate;
380
381         sub foo {
382             my $self   = shift;
383             my %params = validated_hash(
384                 \@_,
385                 bar => { isa => 'Str', default => 'Moose' },
386             );
387             ...
388         }
389
390       MooseX::Params::Validate also supports coercions.
391
392       There are several more powerful extensions that support method
393       parameter validation using Moose types, including
394       MooseX::Method::Signatures, which gives you a full-blown "method"
395       keyword.
396
397         method morning (Str $name) {
398             $self->say("Good morning ${name}!");
399         }
400

LOAD ORDER ISSUES

402       Because Moose types are defined at runtime, you may run into load order
403       problems. In particular, you may want to use a class's type constraint
404       before that type has been defined.
405
406       We have several recommendations for ameliorating this problem. First,
407       define all of your custom types in one module, "MyApp::Types". Second,
408       load this module in all of your other modules.
409

AUTHOR

411       Dave Rolsky <autarch@urth.org>
412
414       Copyright 2009 by Infinity Interactive, Inc.
415
416       <http://www.iinteractive.com>
417
418       This library is free software; you can redistribute it and/or modify it
419       under the same terms as Perl itself.
420
421
422
423perl v5.12.2                      2010-08-21           Moose::Manual::Types(3)
Impressum