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

NAME

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

VERSION

9       version 2.2203
10

TYPES IN PERL?

12       Moose provides its own type system for attributes. You can also use
13       these types to validate method parameters with the help of a MooseX
14       module.
15
16       Moose's type system is based on a combination of Perl 5's own implicit
17       types and some Perl 6 concepts. You can create your own subtypes with
18       custom constraints, making it easy to express any sort of validation.
19
20       Types have names, and you can re-use them by name, making it easy to
21       share types throughout a large application.
22
23       However, this is not a "real" type system. Moose does not magically
24       make Perl start associating types with variables. This is just an
25       advanced parameter checking system which allows you to associate a name
26       with a constraint.
27
28       That said, it's still pretty damn useful, and we think it's one of the
29       things that makes Moose both fun and powerful. Taking advantage of the
30       type system makes it much easier to ensure that you are getting valid
31       data, and it also contributes greatly to code maintainability.
32

THE TYPES

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
43                         Str
44                             Num
45                                 Int
46                             ClassName
47                             RoleName
48                     Ref
49                         ScalarRef[`a]
50                         ArrayRef[`a]
51                         HashRef[`a]
52                         CodeRef
53                         RegexpRef
54                         GlobRef
55                         FileHandle
56                         Object
57
58       In practice, the only difference between "Any" and "Item" is
59       conceptual. "Item" is used as the top-level type in the hierarchy.
60
61       The rest of these types correspond to existing Perl concepts.  In
62       particular:
63
64       •   "Bool" accepts 1 for true, and undef, 0, or the empty string as
65           false.
66
67       •   "Maybe[`a]" accepts either "`a" or "undef".
68
69       •   "Num" accepts integers, floating point numbers (both in decimal
70           notation & exponential notation), 0, .0, 0.0 etc. It doesn't accept
71           numbers with whitespace, Inf, Infinity, "0 but true", NaN & other
72           such strings.
73
74       •   "ClassName" and "RoleName" accept strings that are either the name
75           of a class or the name of a role. The class/role must already be
76           loaded when the constraint is checked.
77
78       •   "FileHandle" accepts either an IO::Handle object or a builtin perl
79           filehandle (see "openhandle" in Scalar::Util).
80
81       •   "Object" accepts any blessed reference.
82
83       The types followed by "[`a]" can be parameterized. So instead of just
84       plain "ArrayRef" we can say that we want "ArrayRef[Int]" instead. We
85       can even do something like "HashRef[ArrayRef[Str]]".
86
87       The "Maybe[`a]" type deserves a special mention. Used by itself, it
88       doesn't really mean anything (and is equivalent to "Item"). When it is
89       parameterized, it means that the value is either "undef" or the
90       parameterized type. So "Maybe[Int]" means an integer or "undef".
91
92       For more details on the type hierarchy, see
93       Moose::Util::TypeConstraints.
94

WHAT IS A TYPE?

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

SUBTYPES

143       Moose uses subtypes in its built-in hierarchy. For example, "Int" is a
144       child of "Num".
145
146       A subtype is defined in terms of a parent type and a constraint. Any
147       constraints defined by the parent(s) will be checked first, followed by
148       constraints defined by the subtype. A value must pass all of these
149       checks to be valid for the subtype.
150
151       Typically, a subtype takes the parent's constraint and makes it more
152       specific.
153
154       A subtype can also define its own constraint failure message. This lets
155       you do things like have an error "The value you provided (20), was not
156       a valid rating, which must be a number from 1-10." This is much
157       friendlier than the default error, which just says that the value
158       failed a validation check for the type. The default error can, however,
159       be made more friendly by installing Devel::PartialDump (version 0.14 or
160       higher), which Moose will use if possible to display the invalid value.
161
162       Here's a simple (and useful) subtype example:
163
164         subtype 'PositiveInt',
165             as 'Int',
166             where { $_ > 0 },
167             message { "The number you provided, $_, was not a positive number" };
168
169       Note that the sugar functions for working with types are all exported
170       by Moose::Util::TypeConstraints.
171

TYPE NAMES

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

COERCION

203       A coercion lets you tell Moose to automatically convert one type to
204       another.
205
206         subtype 'ArrayRefOfInts',
207             as 'ArrayRef[Int]';
208
209         coerce 'ArrayRefOfInts',
210             from 'Int',
211             via { [ $_ ] };
212
213       You'll note that we created a subtype rather than coercing
214       "ArrayRef[Int]" directly. It's a bad idea to add coercions to the raw
215       built in types.
216
217       Coercions are global, just like type names, so a coercion applied to a
218       built in type is seen by all modules using Moose types. This is another
219       reason why it is good to namespace your types.
220
221       Moose will never try to coerce a value unless you explicitly ask for
222       it. This is done by setting the "coerce" attribute option to a true
223       value:
224
225         package Foo;
226
227         has 'sizes' => (
228             is     => 'ro',
229             isa    => 'ArrayRefOfInts',
230             coerce => 1,
231         );
232
233         Foo->new( sizes => 42 );
234
235       This code example will do the right thing, and the newly created object
236       will have "[ 42 ]" as its "sizes" attribute.
237
238   Deep coercion
239       Deep coercion is the coercion of type parameters for parameterized
240       types. Let's take these types as an example:
241
242         subtype 'HexNum',
243             as 'Str',
244             where { /[a-f0-9]/i };
245
246         coerce 'Int',
247             from 'HexNum',
248             via { hex $_ };
249
250         has 'sizes' => (
251             is     => 'ro',
252             isa    => 'ArrayRef[Int]',
253             coerce => 1,
254         );
255
256       If we try passing an array reference of hex numbers for the "sizes"
257       attribute, Moose will not do any coercion.
258
259       However, you can define a set of subtypes to enable coercion between
260       two parameterized types.
261
262         subtype 'ArrayRefOfHexNums',
263             as 'ArrayRef[HexNum]';
264
265         subtype 'ArrayRefOfInts',
266             as 'ArrayRef[Int]';
267
268         coerce 'ArrayRefOfInts',
269             from 'ArrayRefOfHexNums',
270             via { [ map { hex } @{$_} ] };
271
272         Foo->new( sizes => [ 'a1', 'ff', '22' ] );
273
274       Now Moose will coerce the hex numbers to integers.
275
276       Moose does not attempt to chain coercions, so it will not coerce a
277       single hex number. To do that, we need to define a separate 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         duck_type 'CanPrint', [qw(print)];
308
309       We can coerce file handles to an object that satisfies this condition
310       with a simple wrapper class:
311
312         package FHWrapper;
313
314         use Moose;
315
316         has 'handle' => (
317             is  => 'rw',
318             isa => 'FileHandle',
319         );
320
321         sub print {
322             my $self = shift;
323             my $fh   = $self->handle();
324
325             print {$fh} @_;
326         }
327
328       Now we can define a coercion from "FileHandle" to our wrapper class:
329
330         coerce 'CanPrint'
331             => from 'FileHandle'
332             => via { FHWrapper->new( handle => $_ ) };
333
334         has 'output' => (
335             is     => 'rw',
336             isa    => 'CanPrint',
337             coerce => 1,
338         );
339
340       This pattern of using a coercion instead of a type union will help make
341       your class internals simpler.
342

TYPE CREATION HELPERS

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

ANONYMOUS TYPES

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

VALIDATING METHOD PARAMETERS

370       Moose does not provide any means of validating method parameters.
371       However, there are several MooseX extensions on CPAN which let you do
372       this.
373
374       The simplest and least sugary is Params::ValidationCompiler. This lets
375       you validate a set of named parameters using Moose types:
376
377         use Moose::Util::TypeConstraints qw( find_type_constraint );
378         use Params::ValidationCompiler qw( validation_for );
379
380         {
381             my $validator = validation_for(
382                 params => {
383                     foo => { type => find_type_constraint('Int') },
384                     bar => {
385                         type     => find_type_constraint('Str'),
386                         optional => 1,
387                     },
388                     baz => {
389                         type    => find_type_constraint('Int'),
390                         default => 42,
391                     },
392                 },
393             );
394
395             sub foo {
396                 my %args = $validator->(@_);
397             }
398       }
399
400       Params::ValidationCompiler also supports coercions.
401
402       There are several more powerful extensions that support method
403       parameter validation using Moose types, including Moops, which gives
404       you a full-blown "method" keyword.
405
406         method morning ( Str $name ) {
407             $self->say("Good morning ${name}!");
408         }
409

LOAD ORDER ISSUES

411       Because Moose types are defined at runtime, you may run into load order
412       problems. In particular, you may want to use a class's type constraint
413       before that type has been defined.
414
415       In order to ameliorate this problem, we recommend defining all of your
416       custom types in one module, "MyApp::Types", and then loading this
417       module in all of your other modules.
418

AUTHORS

420       •   Stevan Little <stevan@cpan.org>
421
422       •   Dave Rolsky <autarch@urth.org>
423
424       •   Jesse Luehrs <doy@cpan.org>
425
426       •   Shawn M Moore <sartak@cpan.org>
427
428       •   יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
429
430       •   Karen Etheridge <ether@cpan.org>
431
432       •   Florian Ragwitz <rafl@debian.org>
433
434       •   Hans Dieter Pearcey <hdp@cpan.org>
435
436       •   Chris Prather <chris@prather.org>
437
438       •   Matt S Trout <mstrout@cpan.org>
439
441       This software is copyright (c) 2006 by Infinity Interactive, Inc.
442
443       This is free software; you can redistribute it and/or modify it under
444       the same terms as the Perl 5 programming language system itself.
445
446
447
448perl v5.36.0                      2023-02-06           Moose::Manual::Types(3)
Impressum