add curried_arguments, usable from hashref handles
[gitmo/Moose.git] / lib / Moose / Manual / Types.pod
index 6fa9753..2b3a575 100644 (file)
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-Moose::Manual::Types - Moose's Type System
+Moose::Manual::Types - Moose's type system
 
 =head1 TYPES IN PERL?
 
@@ -43,6 +43,7 @@ The basic Moose type hierarchy looks like this
                 Int
               Str
                 ClassName
+                RoleName
           Ref
               ScalarRef
               ArrayRef[`a]
@@ -58,7 +59,7 @@ In practice, the only difference between C<Any> and C<Item> is
 conceptual. C<Item> is used as the top-level type in the hierarchy.
 
 The rest of these types correspond to existing Perl concepts. For
-example, a C<Num> is anything that Perl thinks looks like a number. An
+example, a C<Num> is anything that Perl thinks looks like a number, an
 C<Object> is a blessed reference, etc.
 
 The types followed by "[`a]" can be parameterized. So instead of just
@@ -68,7 +69,7 @@ can even do something like C<HashRef[ArrayRef[Str]]>.
 The C<Maybe[`a]> type deserves a special mention. Used by itself, it
 doesn't really mean anything (and is equivalent to C<Item>). When it
 is parameterized, it means that the value is either C<undef> or the
-parameterized type. So C<Maybe[Int]> means an integer or C<undef>
+parameterized type. So C<Maybe[Int]> means an integer or C<undef>.
 
 For more details on the type hierarchy, see
 L<Moose::Util::TypeConstraints>.
@@ -78,7 +79,7 @@ L<Moose::Util::TypeConstraints>.
 It's important to realize that types are not classes (or
 packages). Types are just objects (L<Moose::Meta::TypeConstraint>
 objects, to be exact) with a name and a constraint. Moose maintains a
-global type registry that lets it convert names like "Num" into the
+global type registry that lets it convert names like C<Num> into the
 appropriate object.
 
 However, class names I<can be> type names. When you define a new class
@@ -91,7 +92,7 @@ using Moose, it defines an associated type name behind the scenes:
 Now you can use C<'MyApp::User'> as a type name:
 
   has creator => (
-      is  => 'rw',
+      is  => 'ro',
       isa => 'MyApp::User',
   );
 
@@ -101,7 +102,7 @@ assumes that any unknown type name passed as the C<isa> value for an
 attribute is a class. So this works:
 
   has 'birth_date' => (
-      is  => 'rw',
+      is  => 'ro',
       isa => 'DateTime',
   );
 
@@ -118,18 +119,18 @@ that the name is a class:
       isa => 'ArrayRef[DateTime]',
   );
 
-Moose will assume that "DateTime" is a class name in both of these
+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. C<Int> is a child of
-C<Num> for example.
+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, and then
-the the subtype's . A value must pass I<all> of these checks to be
-valid for the subtype.
+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.
@@ -150,7 +151,7 @@ Here's a simple (and useful) subtype example:
 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)
+=head2 Creating a new type (that isn't a subtype)
 
 You can also create new top-level types:
 
@@ -177,16 +178,25 @@ 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".
+"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.
+
+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
+
+  has 'counter' => (is => 'rw', isa => PositiveInt);
 
-Type names are just strings. We recommend that you I<do not> use "::"
-as a separator in type names. This can be very confusing, because
-class names are I<also> valid type names! Using something else, like a
-period, makes it clear that "MyApp::User" is a class and
-"MyApp.Type.PositiveInt" is a Moose type defined by your application.
+rather than needing to fully qualify them everywhere. It also allows
 
-The C<MooseX::Types> module lets you create bareword aliases to longer
-names and also automatically namespaces all the types you define.
+  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.
 
 =head1 COERCION
 
@@ -207,12 +217,12 @@ works.
 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 parameter to a true value:
+C<coerce> attribute option to a true value:
 
   package Foo;
 
   has 'sizes' => (
-      is     => 'rw',
+      is     => 'ro',
       isa    => 'ArrayRefOfInts',
       coerce => 1,
   );
@@ -222,7 +232,7 @@ C<coerce> attribute parameter to a true value:
 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
+=head2 Deep coercion
 
 Deep coercion is the coercion of type parameters for parameterized
 types. Let's take these types as an example:
@@ -236,7 +246,7 @@ types. Let's take these types as an example:
       => via { hex $_ };
 
   has 'sizes' => (
-      is     => 'rw',
+      is     => 'ro',
       isa    => 'ArrayRef[Int]',
       coerce => 1,
   );
@@ -306,7 +316,7 @@ with a simple wrapper class:
   use Moose;
 
   has 'handle' => (
-      is  => 'ro',
+      is  => 'rw',
       isa => 'FileHandle',
   );
 
@@ -344,16 +354,16 @@ subtype of C<Str> that only allows the specified values:
 
   enum 'RGB' => qw( red green blue );
 
-This creates a type named C<RGB>
+This creates a type named C<RGB>.
 
 =head1 ANONYMOUS TYPES
 
 All of the type creation functions return a type object. This type
 object can be used wherever you would use a type name, as a parent
-type, or as the value for an attribute's C<isa> parameter:
+type, or as the value for an attribute's C<isa> option:
 
   has 'size' => (
-      is => 'rw',
+      is => 'ro',
       isa => subtype 'Int' => where { $_ > 0 },
   );
 
@@ -366,7 +376,7 @@ Moose does not provide any means of validating method
 parameters. However, there are several MooseX extensions on CPAN which
 let you do this.
 
-The simplest and least sugary is C<MooseX::Params::Validate>. This
+The simplest and least sugary is L<MooseX::Params::Validate>. This
 lets you validate a set of named parameters using Moose types:
 
   use Moose;
@@ -381,11 +391,11 @@ lets you validate a set of named parameters using Moose types:
       ...
   }
 
-C<MooseX::Params::Validate> also supports coercions.
+L<MooseX::Params::Validate> also supports coercions.
 
 There are several more powerful extensions that support method
 parameter validation using Moose types, including
-C<MooseX::Method::Signatures>, which gives you a full-blown C<method>
+L<MooseX::Method::Signatures>, which gives you a full-blown C<method>
 keyword.
 
   method morning (Str $name) {
@@ -408,7 +418,7 @@ C<find_type_constraint> function exported by
 L<Moose::Util::TypeConstraints>:
 
   class_type('MyApp::User')
-      unless find_type_constraint('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.