X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FTypes%2FTypeDecorator.pm;h=12c7f4803b3bacd785f2913b07d38b3d41203974;hb=442e42ba3e90b69452a0c8c2a78cd55d2304262a;hp=cf3f51766d10d6da9e63b6f5338d7200cb7ad36c;hpb=686e58885d32547acf17d5d66b8ca5836a9af584;p=gitmo%2FMooseX-Types.git diff --git a/lib/MooseX/Types/TypeDecorator.pm b/lib/MooseX/Types/TypeDecorator.pm index cf3f517..12c7f48 100644 --- a/lib/MooseX/Types/TypeDecorator.pm +++ b/lib/MooseX/Types/TypeDecorator.pm @@ -3,24 +3,37 @@ package MooseX::Types::TypeDecorator; use strict; use warnings; + use Carp::Clan qw( ^MooseX::Types ); use Moose::Util::TypeConstraints (); use Moose::Meta::TypeConstraint::Union; +use Scalar::Util qw(blessed); use overload( '""' => sub { - return shift->__type_constraint->name; + my $self = shift @_; + if(blessed $self) { + return $self->__type_constraint->name; + } else { + return "$self"; + } }, '|' => sub { ## It's kind of ugly that we need to know about Union Types, but this ## is needed for syntax compatibility. Maybe someday we'll all just do ## Or[Str,Str,Int] - - my @tc = grep {ref $_} @_; + + my @tc = map { + blessed $_ ? $_ : + Moose::Util::TypeConstraints::find_or_parse_type_constraint($_) + } @_; + my $union = Moose::Meta::TypeConstraint::Union->new(type_constraints=>\@tc); return Moose::Util::TypeConstraints::register_type_constraint($union); }, + fallback => 1, + ); =head1 NAME @@ -45,31 +58,40 @@ Old school instantiation sub new { my $class = shift @_; if(my $arg = shift @_) { - if(ref $arg && $arg->isa('Moose::Meta::TypeConstraint')) { + if(blessed $arg && $arg->isa('Moose::Meta::TypeConstraint')) { return bless {'__type_constraint'=>$arg}, $class; - } elsif(ref $arg && $arg->isa('MooseX::Types::UndefinedType')) { + } elsif( + blessed $arg && + $arg->isa('MooseX::Types::UndefinedType') + ) { ## stub in case we'll need to handle these types differently return bless {'__type_constraint'=>$arg}, $class; + } elsif(blessed $arg) { + croak "Argument must be ->isa('Moose::Meta::TypeConstraint') or ->isa('MooseX::Types::UndefinedType'), not ". blessed $arg; } else { - croak "Argument must be ->isa('Moose::Meta::TypeConstraint') or ->isa('MooseX::Types::UndefinedType')"; + croak "Argument cannot be '$arg'"; } } else { - croak "This method [new] requires a single argument of 'arg'."; + croak "This method [new] requires a single argument."; } } -=head __type_constraint ($type_constraint) +=head2 __type_constraint ($type_constraint) Set/Get the type_constraint. =cut sub __type_constraint { - my $self = shift @_; - if(defined(my $tc = shift @_)) { - $self->{__type_constraint} = $tc; + my $self = shift @_; + if(blessed $self) { + if(defined(my $tc = shift @_)) { + $self->{__type_constraint} = $tc; + } + return $self->{__type_constraint}; + } else { + croak 'cannot call __type_constraint as a class method'; } - return $self->{__type_constraint}; } =head2 isa @@ -79,9 +101,13 @@ handle $self->isa since AUTOLOAD can't. =cut sub isa { - my ($self, $target) = @_; + my ($self, $target) = @_; if(defined $target) { - return $self->__type_constraint->isa($target); + if(blessed $self) { + return $self->__type_constraint->isa($target); + } else { + return; + } } else { return; } @@ -96,12 +122,30 @@ handle $self->can since AUTOLOAD can't. sub can { my ($self, $target) = @_; if(defined $target) { - return $self->__type_constraint->can($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; + } +} + + =head2 DESTROY We might need it later @@ -119,12 +163,22 @@ Delegate to the decorator targe =cut sub AUTOLOAD { + my ($self, @args) = @_; my ($method) = (our $AUTOLOAD =~ /([^:]+)$/); - if($self->__type_constraint->can($method)) { - return $self->__type_constraint->$method(@args); + + ## 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($@) { + croak $@; } else { - croak "Method '$method' is not supported"; + return $return; } }