bump version to 0.91
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
index 2f4f1c4..b0ecf5c 100644 (file)
@@ -1,15 +1,12 @@
 
 package Moose::Util::TypeConstraints;
 
-use strict;
-use warnings;
-
 use Carp ();
 use List::MoreUtils qw( all any );
 use Scalar::Util qw( blessed reftype );
 use Moose::Exporter;
 
-our $VERSION = '0.74';
+our $VERSION = '0.91';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
@@ -35,6 +32,7 @@ use Moose::Meta::TypeConstraint::Parameterizable;
 use Moose::Meta::TypeConstraint::Class;
 use Moose::Meta::TypeConstraint::Role;
 use Moose::Meta::TypeConstraint::Enum;
+use Moose::Meta::TypeConstraint::DuckType;
 use Moose::Meta::TypeCoercion;
 use Moose::Meta::TypeCoercion::Union;
 use Moose::Meta::TypeConstraint::Registry;
@@ -369,20 +367,9 @@ sub duck_type {
     }
 
     register_type_constraint(
-        _create_type_constraint(
+        create_duck_type_constraint(
             $type_name,
-            'Object',
-            sub {
-                my $obj = $_;
-                return 0 unless all { $obj->can($_) } @methods;
-                return 1;
-            },
-            sub {
-                my $obj = $_;
-                my @missing_methods = grep { !$obj->can($_) } @methods;
-                return
-                    "${\blessed($obj)} is missing methods '@missing_methods'";
-            },
+            \@methods,
         )
     );
 }
@@ -446,6 +433,15 @@ sub create_enum_type_constraint {
     );
 }
 
+sub create_duck_type_constraint {
+    my ( $type_name, $methods ) = @_;
+
+    Moose::Meta::TypeConstraint::DuckType->new(
+        name => $type_name || '__ANON__',
+        methods => $methods,
+    );
+}
+
 ## --------------------------------------------------------
 ## desugaring functions ...
 ## --------------------------------------------------------
@@ -509,7 +505,7 @@ sub _install_type_coercions ($$) {
     my $type = find_type_constraint($type_name);
     ( defined $type )
         || __PACKAGE__->_throw_error(
-        "Cannot find type '$type_name', perhaps you forgot to load it.");
+        "Cannot find type '$type_name', perhaps you forgot to load it");
     if ( $type->has_coercion ) {
         $type->coercion->add_type_coercions(@$coercion_map);
     }
@@ -607,6 +603,7 @@ $_->make_immutable(
     Moose::Meta::TypeConstraint::Class
     Moose::Meta::TypeConstraint::Role
     Moose::Meta::TypeConstraint::Enum
+    Moose::Meta::TypeConstraint::DuckType
     Moose::Meta::TypeConstraint::Registry
 );
 
@@ -660,6 +657,7 @@ subtype 'Object' => as 'Ref' =>
     where { blessed($_) && blessed($_) ne 'Regexp' } =>
     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
 
+# This type is deprecated.
 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
 
@@ -851,10 +849,10 @@ that hierarchy represented visually.
       Defined
           Value
               Num
-                Int
+                  Int
               Str
-                ClassName
-                RoleName
+                  ClassName
+                  RoleName
           Ref
               ScalarRef
               ArrayRef[`a]
@@ -862,9 +860,8 @@ that hierarchy represented visually.
               CodeRef
               RegexpRef
               GlobRef
-                FileHandle
+                  FileHandle
               Object
-                Role
 
 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
 parameterized, this means you can say:
@@ -890,8 +887,7 @@ existence check. This means that your class B<must> be loaded for this
 type constraint to pass.
 
 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
-name> which is a role, like C<'MyApp::Role::Comparable'>. The C<Role>
-constraint checks that an I<object does> the named role.
+name> which is a role, like C<'MyApp::Role::Comparable'>.
 
 =head2 Type Constraint Naming
 
@@ -953,7 +949,7 @@ See the L<SYNOPSIS> for an example of how to use these.
 
 =over 4
 
-=item B<subtype 'Name' => as 'Parent' => where { } ...>
+=item B<< subtype 'Name' => as 'Parent' => where { } ... >>
 
 This creates a named subtype.
 
@@ -969,7 +965,7 @@ name and a hashref of parameters:
 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
 and C<optimize_as>.
 
-=item B<subtype as 'Parent' => where { } ...>
+=item B<< subtype as 'Parent' => where { } ... >>
 
 This creates an unnamed subtype and will return the type
 constraint meta-object, which will be an instance of
@@ -1071,7 +1067,7 @@ B<NOTE:> You should only use this if you know what you are doing,
 all the built in types use this, so your subtypes (assuming they
 are shallow) will not likely need to use this.
 
-=item B<type 'Name' => where { } ... >
+=item B<< type 'Name' => where { } ... >>
 
 This creates a base type, which has no parent.
 
@@ -1181,6 +1177,11 @@ L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
 Given a enum name this function will create a new
 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
 
+=item B<create_duck_type_constraint($name, $methods)>
+
+Given a duck type name this function will create a new
+L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
+
 =item B<find_or_parse_type_constraint($type_name)>
 
 Given a type name, this first attempts to find a matching constraint