Moose
view release on metacpan or search on metacpan
lib/Moose/Manual/Types.pod view on Meta::CPAN
Moose will assume that C<DateTime> is a class name in both of these
instances.
=head1 SUBTYPES
Moose uses subtypes in its built-in hierarchy. For example, C<Int> is
a child of C<Num>.
A subtype is defined in terms of a parent type and a constraint. Any
constraints defined by the parent(s) will be checked first, followed by
constraints defined by the subtype. A value must pass I<all> of these
checks to be valid for the subtype.
Typically, a subtype takes the parent's constraint and makes it more
specific.
A subtype can also define its own constraint failure message. This
lets you do things like have an error "The value you provided (20),
was not a valid rating, which must be a number from 1-10." This is
much friendlier than the default error, which just says that the value
failed a validation check for the type. The default error can, however,
be made more friendly by installing L<Devel::PartialDump> (version 0.14 or
higher), which Moose will use if possible to display the invalid value.
Here's a simple (and useful) subtype example:
subtype 'PositiveInt',
as 'Int',
where { $_ > 0 },
message { "The number you provided, $_, was not a positive number" };
Note that the sugar functions for working with types are all exported
by L<Moose::Util::TypeConstraints>.
=head1 TYPE NAMES
Type names are global throughout the current Perl
interpreter. Internally, Moose maps names to type objects via a
L<registry|Moose::Meta::TypeConstraint::Registry>.
If you have multiple apps or libraries all using Moose in the same
process, you could have problems with collisions. We recommend that
you prefix names with some sort of namespace indicator to prevent
these sorts of collisions.
For example, instead of calling a type "PositiveInt", call it
"MyApp::Type::PositiveInt" or "MyApp::Types::PositiveInt". We
recommend that you centralize all of these definitions in a single
package, C<MyApp::Types>, which can be loaded by other classes in your
application.
However, before you do this, you should look at the L<MooseX::Types>
module. This module makes it easy to create a "type library" module, which can
export your types as perl constants.
has 'counter' => (is => 'rw', isa => PositiveInt);
This lets you use a short name rather than needing to fully qualify the name
everywhere. It also allows you to easily create parameterized types:
has 'counts' => (is => 'ro', isa => HashRef[PositiveInt]);
This module will check your names at compile time, and is generally more
robust than the string type parsing for complex cases.
=head1 COERCION
A coercion lets you tell Moose to automatically convert one type to another.
subtype 'ArrayRefOfInts',
as 'ArrayRef[Int]';
coerce 'ArrayRefOfInts',
from 'Int',
via { [ $_ ] };
You'll note that we created a subtype rather than coercing C<ArrayRef[Int]>
directly. It's a bad idea to add coercions to the raw built in
types.
Coercions are global, just like type names, so a coercion applied to a built
in type is seen by all modules using Moose types. This is I<another> reason
why it is good to namespace your types.
Moose will I<never> try to coerce a value unless you explicitly ask for
it. This is done by setting the C<coerce> attribute option to a true value:
package Foo;
has 'sizes' => (
is => 'ro',
isa => 'ArrayRefOfInts',
coerce => 1,
);
Foo->new( sizes => 42 );
This code example will do the right thing, and the newly created
object will have C<[ 42 ]> as its C<sizes> attribute.
=head2 Deep coercion
Deep coercion is the coercion of type parameters for parameterized
types. Let's take these types as an example:
subtype 'HexNum',
as 'Str',
where { /[a-f0-9]/i };
coerce 'Int',
from 'HexNum',
via { hex $_ };
has 'sizes' => (
is => 'ro',
isa => 'ArrayRef[Int]',
coerce => 1,
);
If we try passing an array reference of hex numbers for the C<sizes>
attribute, Moose will not do any coercion.
( run in 2.729 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )