my @try_actions = @{$children->{$try_part}};
TRY_ACTION: foreach my $action (@try_actions) {
if (my $capture_attr = $action->attributes->{CaptureArgs}) {
- my $capture_count = $capture_attr->[0] || 0;
+ my $capture_count = $action->number_of_captures|| 0;
# Short-circuit if not enough remaining parts
next TRY_ACTION unless @parts >= $capture_count;
push(@captures, splice(@parts, 0, $capture_count));
# check if the action may fit, depending on a given test by the app
- if ($action->can('match_captures')) { next TRY_ACTION unless $action->match_captures($c, \@captures) }
+ next TRY_ACTION unless $action->match_captures($c, \@captures);
# try the remaining parts against children of this action
my ($actions, $captures, $action_parts, $n_pathparts) = $self->recurse_match(
=cut
-sub _check_args_attr {
- my ( $self, $action, $name ) = @_;
-
- return unless exists $action->attributes->{$name};
-
- if (@{$action->attributes->{$name}} > 1) {
- Catalyst::Exception->throw(
- "Multiple $name attributes not supported registering " . $action->reverse()
- );
- }
- my $args = $action->attributes->{$name}->[0];
- if (defined($args) and not (
- Scalar::Util::looks_like_number($args) and
- int($args) == $args and $args >= 0
- )) {
- require Data::Dumper;
- local $Data::Dumper::Terse = 1;
- local $Data::Dumper::Indent = 0;
- $args = Data::Dumper::Dumper($args);
- Catalyst::Exception->throw(
- "Invalid $name($args) for action " . $action->reverse() .
- " (use '$name' or '$name(<number>)')"
- );
- }
-}
-
sub register {
my ( $self, $c, $action ) = @_;
$self->_actions->{'/'.$action->reverse} = $action;
- foreach my $name (qw(Args CaptureArgs)) {
- $self->_check_args_attr($action, $name);
- }
-
if (exists $action->attributes->{Args} and exists $action->attributes->{CaptureArgs}) {
Catalyst::Exception->throw(
"Combining Args and CaptureArgs attributes not supported registering " .
attribute) but has no C<:CaptureArgs> attribute is treated by Catalyst
as a chain end.
+Allowed values for CaptureArgs is a single integer (CaptureArgs(2), meaning two
+allowed) or you can declare a L<Moose>, L<MooseX::Types> or L<Type::Tiny>
+named constraint such as CaptureArgs(Int,Str) would require two args with
+the first being a Integer and the second a string. You may declare your own
+custom type constraints and import them into the controller namespace:
+
+ package MyApp::Controller::Root;
+
+ use Moose;
+ use MooseX::MethodAttributes;
+ use MyApp::Types qw/Int/;
+
+ extends 'Catalyst::Controller';
+
+ sub chain_base :Chained(/) CaptureArgs(1) { }
+
+ sub any_priority_chain :Chained(chain_base) PathPart('') Args(1) { }
+
+ sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { }
+
+See L<Catalyst::RouteMatching> for more.
+
=item Args
By default, endpoints receive the rest of the arguments in the path. You