From: Stevan Little Date: Thu, 29 Nov 2007 13:42:53 +0000 (+0000) Subject: fixing a bug for Sartak X-Git-Tag: 0_32~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=41e007e41e1dd7b10b59208da01afb9e711ec90a;p=gitmo%2FMoose.git fixing a bug for Sartak --- diff --git a/Changes b/Changes index 3200d20..1545f4f 100644 --- 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 diff --git a/lib/Moose/Meta/TypeCoercion.pm b/lib/Moose/Meta/TypeCoercion.pm index 35fa726..0954307 100644 --- a/lib/Moose/Meta/TypeCoercion.pm +++ b/lib/Moose/Meta/TypeCoercion.pm @@ -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 +=item B + +=item B + =back =head1 BUGS diff --git a/lib/Moose/Meta/TypeCoercion/Union.pm b/lib/Moose/Meta/TypeCoercion/Union.pm index ef1d174..4aa29fd 100644 --- a/lib/Moose/Meta/TypeCoercion/Union.pm +++ b/lib/Moose/Meta/TypeCoercion/Union.pm @@ -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 +=item B + +=item B + =back =head1 BUGS diff --git a/lib/Moose/Util/TypeConstraints.pm b/lib/Moose/Util/TypeConstraints.pm index dbfe58d..ac82b6a 100644 --- a/lib/Moose/Util/TypeConstraints.pm +++ b/lib/Moose/Util/TypeConstraints.pm @@ -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); + } } ## -------------------------------------------------------- diff --git a/t/040_type_constraints/007_util_more_type_coercion.t b/t/040_type_constraints/007_util_more_type_coercion.t index e61538f..6480222 100644 --- a/t/040_type_constraints/007_util_more_type_coercion.t +++ b/t/040_type_constraints/007_util_more_type_coercion.t @@ -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]) };