fixing a bug for Sartak
Stevan Little [Thu, 29 Nov 2007 13:42:53 +0000 (13:42 +0000)]
Changes
lib/Moose/Meta/TypeCoercion.pm
lib/Moose/Meta/TypeCoercion/Union.pm
lib/Moose/Util/TypeConstraints.pm
t/040_type_constraints/007_util_more_type_coercion.t

diff --git a/Changes b/Changes
index 3200d20..1545f4f 100644 (file)
--- a/Changes
+++ b/Changes
@@ -5,12 +5,23 @@ Revision history for Perl extension Moose
       - fixing how subtype aliases of unions work
         they should inherit the parent's coercion
         - added tests for this
+      - you can now define multiple coercions on 
+        a single type at different times instead of
+        having to do it all in one place
+        - added tests for this
       
     * Moose::Meta::TypeConstraint
       - there is now a default constraint of sub { 1 }
         instead of Moose::Util::TypeConstraints setting
         this for us
 
+    * Moose::Meta::TypeCoercion 
+    * Moose::Meta::TypeCoercion::Union    
+      - added the &has_coercion_for_type and 
+        &add_type_coercions methods to support the 
+        new features above (although you cannot add
+        more type coercions for Union types)
+
 0.31 Mon. Nov. 26, 2007
     * Moose::Meta::Attribute
       - made the +attr syntax handle extending types with 
index 35fa726..0954307 100644 (file)
@@ -10,7 +10,7 @@ use Carp 'confess';
 use Moose::Meta::Attribute;
 use Moose::Util::TypeConstraints ();
 
-our $VERSION   = '0.03';
+our $VERSION   = '0.04';
 our $AUTHORITY = 'cpan:STEVAN';
 
 __PACKAGE__->meta->add_attribute('type_coercion_map' => (
@@ -33,7 +33,7 @@ __PACKAGE__->meta->add_attribute('compiled_type_coercion' => (
 sub new { 
     my $class = shift;
     my $self  = $class->meta->new_object(@_);
-    $self->compile_type_coercion();
+    $self->compile_type_coercion;
     return $self;
 }
 
@@ -64,6 +64,31 @@ sub compile_type_coercion {
     });    
 }
 
+sub has_coercion_for_type {
+    my ($self, $type_name) = @_;
+    my %coercion_map = @{$self->type_coercion_map};
+    exists $coercion_map{$type_name} ? 1 : 0;
+}
+
+sub add_type_coercions {
+    my ($self, @new_coercion_map) = @_;
+        
+    my $coercion_map = $self->type_coercion_map;    
+    my %has_coercion = @$coercion_map;
+    
+    while (@new_coercion_map) {
+        my ($constraint_name, $action) = splice(@new_coercion_map, 0, 2);        
+        
+        confess "A coercion action already exists for '$constraint_name'"
+            if exists $has_coercion{$constraint_name};
+        
+        push @{$coercion_map} => ($constraint_name, $action);
+    }
+    
+    # and re-compile ...
+    $self->compile_type_coercion;
+}
+
 sub coerce { $_[0]->_compiled_type_coercion->($_[1]) }
 
 
@@ -104,6 +129,10 @@ If you wish to use features at this depth, please come to the
 
 =item B<type_constraint>
 
+=item B<has_coercion_for_type>
+
+=item B<add_type_coercions>
+
 =back
 
 =head1 BUGS
index ef1d174..4aa29fd 100644 (file)
@@ -8,7 +8,7 @@ use metaclass;
 use Carp         'confess';
 use Scalar::Util 'blessed';
 
-our $VERSION   = '0.01';
+our $VERSION   = '0.02';
 our $AUTHORITY = 'cpan:STEVAN';
 
 use base 'Moose::Meta::TypeCoercion';
@@ -40,6 +40,12 @@ sub compile_type_coercion {
     });
 }
 
+sub has_coercion_for_type { 0 }
+
+sub add_type_coercions {
+    confess "Cannot add additional type coercions to Union types";
+}
+
 1;
 
 __END__
@@ -69,6 +75,10 @@ If you wish to use features at this depth, please come to the
 
 =item B<compile_type_coercion>
 
+=item B<has_coercion_for_type>
+
+=item B<add_type_coercions>
+
 =back
 
 =head1 BUGS
index dbfe58d..ac82b6a 100644 (file)
@@ -301,13 +301,16 @@ sub _create_type_constraint ($$$;$$) {
 sub _install_type_coercions ($$) {
     my ($type_name, $coercion_map) = @_;
     my $type = $REGISTRY->get_type_constraint($type_name);
-    (!$type->has_coercion)
-        || confess "The type coercion for '$type_name' has already been registered";
-    my $type_coercion = Moose::Meta::TypeCoercion->new(
-        type_coercion_map => $coercion_map,
-        type_constraint   => $type
-    );
-    $type->coercion($type_coercion);
+    if ($type->has_coercion) {
+        $type->coercion->add_type_coercions(@$coercion_map);
+    }
+    else {
+        my $type_coercion = Moose::Meta::TypeCoercion->new(
+            type_coercion_map => $coercion_map,
+            type_constraint   => $type
+        );
+        $type->coercion($type_coercion);
+    }
 }
 
 ## --------------------------------------------------------
index e61538f..6480222 100644 (file)
@@ -17,7 +17,9 @@ BEGIN {
     
     coerce 'HTTPHeader'
         => from ArrayRef 
-            => via { HTTPHeader->new(array => $_[0]) }
+            => via { HTTPHeader->new(array => $_[0]) };
+            
+    coerce 'HTTPHeader'
         => from HashRef 
             => via { HTTPHeader->new(hash => $_[0]) };