-=pod
+package Moose::Manual::Types;
+
+# ABSTRACT: Moose's type system
-=head1 NAME
+__END__
-Moose::Manual::Types - Moose's type system
+=pod
=head1 TYPES IN PERL?
module.
Moose's type system is based on a combination of Perl 5's own
-I<implicit> types and some Perl 6 concepts. You can easily create your
+I<implicit> types and some Perl 6 concepts. You can create your
own subtypes with custom constraints, making it easy to express any
sort of validation.
Types have names, and you can re-use them by name, making it easy to
share types throughout a large application.
-Let us be clear that is not a "real" type system. Moose does not
-magically make Perl start associating types with variables. This is
-just an advanced parameter checking system which allows you to
-associate a name with a constraint.
+However, this is not a "real" type system. Moose does not magically make Perl
+start associating types with variables. This is just an advanced parameter
+checking system which allows you to associate a name with a constraint.
That said, it's still pretty damn useful, and we think it's one of the
things that makes Moose both fun and powerful. Taking advantage of the
Defined
Value
Str
- Num
- Int
- ClassName
- RoleName
+ Num
+ Int
+ ClassName
+ RoleName
Ref
- ScalarRef
+ ScalarRef[`a]
ArrayRef[`a]
HashRef[`a]
CodeRef
RegexpRef
GlobRef
- FileHandle
+ FileHandle
Object
In practice, the only difference between C<Any> and C<Item> is
=over 4
-=item C<Bool> accepts C<1> for true, and any value that perl treats as false for false.
+=item
+
+C<Bool> accepts C<1> for true, and undef, 0, or the empty string as false.
+
+=item
+
+C<Maybe[`a]> accepts either C<`a> or C<undef>.
+
+=item
-=item C<Maybe[`a]> accepts either C<`a> or C<undef>.
+C<Num> accepts anything that perl thinks looks like a number (see L<Scalar::Util/looks_like_number>).
-=item C<Num> accepts anything that perl thinks looks like a number (see L<Scalar::Util/looks_like_number>).
+=item
-=item C<ClassName> and C<RoleName> accept strings that are either a the name of a class or the name of a role. The class/role must be loaded beforehand for this to succeed.
+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.
-=item C<FileHandle> accepts either an object of type L<IO::Handle> or a builtin perl filehandle (see L<Scalar::Util/openhandle>).
+=item
-=item C<Object> accepts any blessed reference.
+C<FileHandle> accepts either an L<IO::Handle> object or a builtin perl filehandle (see L<Scalar::Util/openhandle>).
+
+=item
+
+C<Object> accepts any blessed reference.
=back
Note that the sugar functions for working with types are all exported
by L<Moose::Util::TypeConstraints>.
-=head2 Creating a new type (that isn't a subtype)
-
-You can also create new top-level types:
-
- type 'FourCharacters' => where { defined $_ && length $_ == 4 };
-
-In practice, this example is more or less the same as subtyping
-C<Str>, except you have to check definedness yourself.
-
-It's hard to find a case where you wouldn't want to subtype a very
-broad type like C<Defined>, C<Ref> or C<Object>.
-
-Defining a new top-level type is conceptually the same as subtyping
-C<Item>.
-
=head1 TYPE NAMES
Type names are global throughout the current Perl
package, C<MyApp::Types>, which can be loaded by other classes in your
application.
-Once you're doing this, you should almost certainly look at the
-L<MooseX::Types> extension which allows easy declaration of type libraries
-and can export your types as perl constants so that you can refer to them
-as just
+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);
-rather than needing to fully qualify them everywhere. It also allows
+This lets you use a short name rather than needing to fully qualify the name
+everywhere. It also allows you to write easily create parameterized types:
has 'counts' => (is => 'ro', isa => HashRef[PositiveInt]);
-and similarly for the union and other syntax discussed below, which
-will compile time check your use of names and is generally more robust
-than the string type parsing for complex cases.
+This module will check your names at compile time, and is generally more
+robust than the string type parsing for complex cases.
=head1 COERCION
-One of the most powerful features of Moose's type system is its
-coercions. A coercion is a way to convert from one type to another.
+A coercion lets you tell Moose to automatically convert one type to another.
subtype 'ArrayRefOfInts'
=> as 'ArrayRef[Int]';
=> from 'Int'
=> via { [ $_ ] };
-You'll note that we had to create a subtype rather than coercing
-C<ArrayRef[Int]> directly. This is just a quirk of how Moose
-works.
+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, like type names, are global. 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:
+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;
Now Moose will coerce the hex numbers to integers.
-However, Moose does not attempt to chain coercions, so it will not
+Moose does not attempt to chain coercions, so it will not
coerce a single hex number. To do that, we need to define a separate
coercion:
my $self = shift;
my $fh = $self->handle();
- print $fh @_;
+ print {$fh} @_;
}
Now we can define a coercion from C<FileHandle> to our wrapper class:
type, or as the value for an attribute's C<isa> option:
has 'size' => (
- is => 'ro',
- isa => subtype('Int' => where { $_ > 0 }),
+ is => 'ro',
+ isa => subtype( 'Int' => where { $_ > 0 } ),
);
This is handy when you want to create a one-off type and don't want to
L<MooseX::Method::Signatures>, which gives you a full-blown C<method>
keyword.
- method morning (Str $name) {
+ method morning ( Str $name ) {
$self->say("Good morning ${name}!");
}
order problems. In particular, you may want to use a class's type
constraint before that type has been defined.
-We have several recommendations for ameliorating this problem. First,
-define I<all> of your custom types in one module,
-C<MyApp::Types>. Second, load this module in all of your other
-modules.
-
-If you are still having load order problems, you can make use of the
-C<find_type_constraint> function exported by
-L<Moose::Util::TypeConstraints>:
-
- class_type('MyApp::User')
- unless find_type_constraint('MyApp::User');
-
-This sort of "find or create" logic is simple to write, and will let
-you work around load order issues.
-
-=head1 AUTHOR
-
-Dave Rolsky E<lt>autarch@urth.orgE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2009 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+In order to ameliorate this problem, we recommend defining I<all> of your
+custom types in one module, C<MyApp::Types>, and then loading this module in
+all of your other modules.
=cut