fix handling of slurpy arguments in tuples
Graham Knop [Thu, 21 Jul 2022 08:35:13 +0000 (10:35 +0200)]
Type::Tiny version 1.016002 changed how slurpy types are represented.
Catalyst had been looking at the original parameters to a Tuple type,
and expecting a slurpy type to be a hashref as the last parameter. That
is no longer true, so the argument count checking would fail.

For new Type::Tiny versions, we can check that the final parameter is a
Slurpy type. This seems slightly more robust.

lib/Catalyst/Action.pm

index 36f4793..6fa9d19 100644 (file)
@@ -97,12 +97,23 @@ has number_of_args_constraints => (
         $tc->can('is_strictly_a_type_of') &&
         $tc->is_strictly_a_type_of('Tuple'))
       {
-        my @parameters = @{ $tc->parameters||[]};
-        if( defined($parameters[-1]) and exists($parameters[-1]->{slurpy})) {
-          return undef;
-        } else {
-          return my $total_params = scalar(@parameters);
+        my @parameters = @{ $tc->parameters||[] };
+        my $final = $parameters[-1];
+        if ( defined $final ) {
+          if ( blessed $final ) {
+            # modern form of slurpy
+            if ($final->can('is_strictly_a_type_of') && $final->is_strictly_a_type_of('Slurpy')) {
+              return undef;
+            }
+          }
+          else {
+            # old form of slurpy
+            if (ref $final eq 'HASH' && $final->{slurpy}) {
+              return undef;
+            }
+          }
         }
+        return scalar @parameters;
       } elsif($tc->is_a_type_of('Ref')) {
         return undef;
       } else {