X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FTypes%2FTypeDecorator.pm;h=6f028138af5491db08ebeae1ab69c6a93898800b;hb=d7d0bd99611df609fb566d2aa772e002ce0747c3;hp=e55baf496be9dc11d127f1749b5b30942ac33454;hpb=6a9158d85ae17b00a0413201d5ce88fca05c336d;p=gitmo%2FMooseX-Types.git diff --git a/lib/MooseX/Types/TypeDecorator.pm b/lib/MooseX/Types/TypeDecorator.pm index e55baf4..6f02813 100644 --- a/lib/MooseX/Types/TypeDecorator.pm +++ b/lib/MooseX/Types/TypeDecorator.pm @@ -1,10 +1,10 @@ package MooseX::Types::TypeDecorator; -our $VERSION = "0.23"; + +#ABSTRACT: Wraps Moose::Meta::TypeConstraint objects with added features use strict; use warnings; - use Carp::Clan qw( ^MooseX::Types ); use Moose::Util::TypeConstraints (); use Moose::Meta::TypeConstraint::Union; @@ -52,10 +52,6 @@ use overload( ); -=head1 NAME - -MooseX::Types::TypeDecorator - More flexible access to a Type Constraint - =head1 DESCRIPTION This is a decorator object that contains an underlying type constraint. We use @@ -72,7 +68,11 @@ Old school instantiation =cut sub new { - my $class = shift @_; + my $proto = shift; + if (ref($proto)) { + return $proto->_try_delegate('new', @_); + } + my $class = $proto; if(my $arg = shift @_) { if(blessed $arg && $arg->isa('Moose::Meta::TypeConstraint')) { return bless {'__type_constraint'=>$arg}, $class; @@ -117,50 +117,17 @@ handle $self->isa since AUTOLOAD can't. =cut sub isa { - my ($self, $target) = @_; - if(defined $target) { - if(blessed $self) { - return $self->__type_constraint->isa($target); - } else { - return; - } - } else { - return; - } + return 1 if $_[1]->isa('Moose::Meta::TypeConstraint'); + shift->_try_delegate('isa', @_) } - =head2 can handle $self->can since AUTOLOAD can't. =cut -sub can { - my ($self, $target) = @_; - if(defined $target) { - if(blessed $self) { - return $self->__type_constraint->can($target); - } else { - return; - } - } else { - return; - } -} - -=head2 meta - -have meta examine the underlying type constraints - -=cut - -sub meta { - my $self = shift @_; - if(blessed $self) { - return $self->__type_constraint->meta; - } -} +sub can { shift->_try_delegate('can', @_) } =head2 _throw_error @@ -187,33 +154,48 @@ sub DESTROY { =head2 AUTOLOAD -Delegate to the decorator targe +Delegate to the decorator target. =cut sub AUTOLOAD { - my ($self, @args) = @_; my ($method) = (our $AUTOLOAD =~ /([^:]+)$/); ## We delegate with this method in an attempt to support a value of ## __type_constraint which is also AUTOLOADing, in particular the class ## MooseX::Types::UndefinedType which AUTOLOADs during autovivication. - - my $return; - - eval { - $return = $self->__type_constraint->$method(@args); - }; if($@) { - __PACKAGE__->_throw_error($@); - } else { - return $return; - } -} -=head1 AUTHOR + $self->_try_delegate($method, @args); +} -See L. +sub _try_delegate { + my ($self, $method, @args) = @_; + my $tc = $self->__type_constraint; + my $class; + if ($tc->can('is_subtype_of')) { # Union can't + my $search_tc = $tc; + while (1) { + if ($search_tc->isa('Moose::Meta::TypeConstraint::Class')) { + $class = $search_tc->class; + last; + } + $search_tc = $search_tc->parent; + last unless $search_tc->is_subtype_of('Object'); + } + } + + my $inv = ( + $class + ? ( + $method eq 'new' || $class->can($method) + ? $class + : $tc + ) + : $tc + ); + $inv->$method(@args); +} =head1 LICENSE