basic coerces
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Action.pm
index 9622541..6081f22 100644 (file)
@@ -55,7 +55,10 @@ has number_of_args => (
     } elsif(!defined($self->attributes->{Args}[0])) {
       # When its 'Args' that internal cue for 'unlimited'
       return undef;
-    } elsif(looks_like_number($self->attributes->{Args}[0])) {
+    } elsif(
+      scalar(@{$self->attributes->{Args}}) == 1 &&
+      looks_like_number($self->attributes->{Args}[0])
+    ) {
       # 'Old school' numberd args (is allowed to be undef as well)
       return $self->attributes->{Args}[0];
     } else {
@@ -96,12 +99,20 @@ has args_constraints => (
     ) {
       return \@args;
     } else {
-      @args = map { Moose::Util::TypeConstraints::find_or_parse_type_constraint($_) || die "$_ is not a constraint!" } @arg_protos;
+      @args =
+        map {  $self->resolve_type_constraint($_) || die "$_ is not a constraint!" }
+        @arg_protos;
     }
 
     return \@args;
   }
 
+sub resolve_type_constraint {
+  my ($self, $name) = @_;
+  my $tc = eval "package ${\$self->class}; $name" || undef;
+  return $tc || Moose::Util::TypeConstraints::find_or_parse_type_constraint($name);
+}
+
 use overload (
 
     # Stringify to reverse for debug output etc.
@@ -129,17 +140,32 @@ sub execute {
 
 sub match {
     my ( $self, $c ) = @_;
+    $c->log->debug($self->reverse);
 
     # If infinite args, we always match
     return 1 if $self->normalized_arg_number == ~0;
 
     # There there are arg constraints, we must see to it that the constraints
     # check positive for each arg in the list.
-    if($self->has_args_constraints) {
-      for my $i($#{ $c->req->args }) {
-        $self->args_constraints->[$i]->check($c->req->args->[$i]) || return 0;
+    if(0 && $self->has_args_constraints) {
+      # If there is only one type constraint, and its a Ref or subtype of Ref,
+      # That means we expect a reference, so use the full args arrayref.
+      if(
+        $self->number_of_args_constraints == 1 &&
+        ($self->args_constraints->[0]->is_a_type_of('Ref') || $self->args_constraints->[0]->is_a_type_of('ClassName'))
+      ) {
+        return 1 if $self->args_constraints->[0]->check($c->req->args);
+        if($self->args_constraints->[0]->coercion && $self->attributes->{Coerce}) {
+          my $coerced = $self->args_constraints->[0]->coerce($c) || return 0;
+          $c->req->args([$coerced]);
+          return 1;
+        }
+      } else {
+        for my $i(0..$#{ $c->req->args }) {
+          $self->args_constraints->[$i]->check($c->req->args->[$i]) || return 0;
+        }
+        return 1;
       }
-      return 1;
     } else {
       # Otherwise, we just need to match the number of args.
       return scalar( @{ $c->req->args } ) == $self->normalized_arg_number;
@@ -218,6 +244,9 @@ of the captures for this action.
 Returning true from this method causes the chain match to continue, returning
 makes the chain not match (and alternate, less preferred chains will be attempted).
 
+=head2 resolve_type_constraint
+
+Trys to find a type constraint if you have on on a type constrained method.
 
 =head2 compare