X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=lib%2FMouse%2FMeta%2FTypeConstraint.pm;h=155c48ce9fe132c6ba845d77e8fc354df9a538f4;hp=a35b4d0bb222857972d4f4fb0cac1f13c56210dd;hb=f790c46b83718b0665e24380b0df0c387925ea27;hpb=065f79e7cd03765f26c6ea276aaf9b3c5897886a diff --git a/lib/Mouse/Meta/TypeConstraint.pm b/lib/Mouse/Meta/TypeConstraint.pm index a35b4d0..155c48c 100644 --- a/lib/Mouse/Meta/TypeConstraint.pm +++ b/lib/Mouse/Meta/TypeConstraint.pm @@ -2,13 +2,21 @@ package Mouse::Meta::TypeConstraint; use Mouse::Util qw(:meta); # enables strict and warnings use overload + 'bool' => sub { 1 }, # always true + '""' => sub { $_[0]->name }, # stringify to tc name + + '|' => sub { # or-combination + require Mouse::Util::TypeConstraints; + return Mouse::Util::TypeConstraints::find_or_parse_type_constraint( + "$_[0] | $_[1]", + ); + }, + fallback => 1; use Carp (); -my $null_check = sub { 1 }; - sub new { my($class, %args) = @_; @@ -80,61 +88,6 @@ sub create_child_type{ ); } - -sub compile_type_constraint{ - my($self) = @_; - - # add parents first - my @checks; - for(my $parent = $self->parent; defined $parent; $parent = $parent->parent){ - if($parent->{hand_optimized_type_constraint}){ - unshift @checks, $parent->{hand_optimized_type_constraint}; - last; # a hand optimized constraint must include all the parents - } - elsif($parent->{constraint}){ - unshift @checks, $parent->{constraint}; - } - } - - # then add child - if($self->{constraint}){ - push @checks, $self->{constraint}; - } - - if($self->{type_constraints}){ # Union - my @types = map{ $_->_compiled_type_constraint } @{ $self->{type_constraints} }; - push @checks, sub{ - foreach my $c(@types){ - return 1 if $c->($_[0]); - } - return 0; - }; - } - - if(@checks == 0){ - $self->{compiled_type_constraint} = $null_check; - } - elsif(@checks == 1){ - my $c = $checks[0]; - $self->{compiled_type_constraint} = sub{ - my(@args) = @_; - local $_ = $args[0]; - return $c->(@args); - }; - } - else{ - $self->{compiled_type_constraint} = sub{ - my(@args) = @_; - local $_ = $args[0]; - foreach my $c(@checks){ - return undef if !$c->(@args); - } - return 1; - }; - } - return; -} - sub _add_type_coercions{ my $self = shift; @@ -224,6 +177,29 @@ sub is_a_type_of{ return 0; } +# See also Moose::Meta::TypeConstraint::Parameterizable +sub parameterize{ + my($self, $param, $name) = @_; + + if(!ref $param){ + require Mouse::Util::TypeConstraints; + $param = Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint($param); + } + + $name ||= sprintf '%s[%s]', $self->name, $param->name; + + my $generator = $self->{constraint_generator} + || Carp::confess("The $name constraint cannot be used, because $param doesn't subtype from a parameterizable type"); + + return Mouse::Meta::TypeConstraint->new( + name => $name, + parent => $self, + parameter => $param, + constraint => $generator->($param), # must be 'constraint', not 'optimized' + + type => 'Parameterized', + ); +} 1; __END__ @@ -234,7 +210,7 @@ Mouse::Meta::TypeConstraint - The Mouse Type Constraint metaclass =head1 VERSION -This document describes Mouse version 0.40_02 +This document describes Mouse version 0.40_03 =head1 DESCRIPTION