From: Dave Rolsky Date: Fri, 27 Aug 2010 21:15:48 +0000 (-0500) Subject: A horrible hack to make generating a coercion for a type union lazy X-Git-Tag: 1.11~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=70f676ca8f4cff09ab02a06cb979ffe5c59f28f9;p=gitmo%2FMoose.git A horrible hack to make generating a coercion for a type union lazy This fixes a bug that was triggered by recursive type constraints in MX::Types. --- diff --git a/lib/Moose/Meta/TypeConstraint/Union.pm b/lib/Moose/Meta/TypeConstraint/Union.pm index 41654f6..02d55e0 100644 --- a/lib/Moose/Meta/TypeConstraint/Union.pm +++ b/lib/Moose/Meta/TypeConstraint/Union.pm @@ -7,6 +7,7 @@ use metaclass; use Moose::Meta::TypeCoercion::Union; +use List::MoreUtils qw(any); use List::Util qw(first); our $VERSION = '1.10'; @@ -33,13 +34,29 @@ sub new { $self->_set_constraint(sub { $self->check($_[0]) }); - if ( grep { $_->has_coercion } @{ $self->type_constraints } ) { - $self->coercion( - Moose::Meta::TypeCoercion::Union->new( type_constraint => $self ) - ); + return $self; +} + +# XXX - this is a rather gross implementation of laziness for the benefit of +# MX::Types. If we try to call ->has_coercion on the objects during object +# construction, this does not work when defining a recursive constraint with +# MX::Types. +sub coercion { + my $self = shift; + + return $self->{coercion} if exists $self->{coercion}; + + if ( any { $_->has_coercion } @{ $self->type_constraints } ) { + return $self->{coercion} = Moose::Meta::TypeCoercion::Union->new( + type_constraint => $self ); + } + else { + return $self->{coercion} = undef; } +} - return $self; +sub has_coercion { + return defined $_[0]->coercion; } sub _actually_compile_type_constraint { diff --git a/xt/author/pod_coverage.t b/xt/author/pod_coverage.t index cda0317..93232d8 100644 --- a/xt/author/pod_coverage.t +++ b/xt/author/pod_coverage.t @@ -92,10 +92,11 @@ my %trustme = ( [qw( constraint equals get_message )], 'Moose::Meta::TypeConstraint::Parameterizable' => ['.+'], 'Moose::Meta::TypeConstraint::Parameterized' => ['.+'], - 'Moose::Meta::TypeConstraint::Role' => [qw( equals is_a_type_of )], - 'Moose::Meta::TypeConstraint::Union' => ['compile_type_constraint'], - 'Moose::Util' => ['add_method_modifier'], - 'Moose::Util::MetaRole' => ['apply_metaclass_roles'], + 'Moose::Meta::TypeConstraint::Role' => [qw( equals is_a_type_of )], + 'Moose::Meta::TypeConstraint::Union' => + [qw( compile_type_constraint coercion has_coercion)], + 'Moose::Util' => ['add_method_modifier'], + 'Moose::Util::MetaRole' => ['apply_metaclass_roles'], 'Moose::Util::TypeConstraints' => ['find_or_create_type_constraint'], );