X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FDispatchType%2FChained.pm;h=138727c824f30c3d4d301835cbf600f76dd8bbfe;hp=b9d6d07a07a102d32b4e9c2a3585ab13948cdc47;hb=82010ea176741c7a4f2baf3f6f27377b1d9f6b15;hpb=130b45ec858db6863e3d6959f7a6e3b6908cd48e diff --git a/lib/Catalyst/DispatchType/Chained.pm b/lib/Catalyst/DispatchType/Chained.pm index b9d6d07..138727c 100644 --- a/lib/Catalyst/DispatchType/Chained.pm +++ b/lib/Catalyst/DispatchType/Chained.pm @@ -98,7 +98,14 @@ sub list { @{ $self->_endpoints } ) { my $args = $endpoint->list_extra_info->{Args}; - my @parts = (defined($endpoint->attributes->{Args}[0]) ? (("*") x $args) : '...'); + + my @parts; + if($endpoint->has_args_constraints) { + @parts = map { "{$_}" } $endpoint->all_args_constraints; + } elsif(defined $endpoint->attributes->{Args}) { + @parts = (defined($endpoint->attributes->{Args}[0]) ? (("*") x $args) : '...'); + } + my @parents = (); my $parent = "DUMMY"; my $extra = $self->_list_extra_http_methods($endpoint); @@ -107,7 +114,12 @@ sub list { my $curr = $endpoint; while ($curr) { if (my $cap = $curr->list_extra_info->{CaptureArgs}) { - unshift(@parts, (("*") x $cap)); + if($curr->has_captures_constraints) { + my $names = join '/', map { "{$_}" } $curr->all_captures_constraints; + unshift(@parts, $names); + } else { + unshift(@parts, (("*") x $cap)); + } } if (my $pp = $curr->attributes->{PathPart}) { unshift(@parts, $pp->[0]) @@ -150,13 +162,14 @@ sub list { push(@rows, [ '', $name ]); } + my $endpoint_arg_info = $endpoint; if($endpoint->has_args_constraints) { my $tc = join ',', @{$endpoint->args_constraints}; - $endpoint .= " ($tc)"; + $endpoint_arg_info .= " ($tc)"; } else { - $endpoint .= defined($endpoint->attributes->{Args}[0]) ? " ($args)" : " (...)"; + $endpoint_arg_info .= defined($endpoint->attributes->{Args}[0]) ? " ($args)" : " (...)"; } - push(@rows, [ '', (@rows ? "=> " : '').($extra ? "$extra " : ''). ($scheme ? "$scheme: ":'')."/${endpoint}". ($consumes ? " :$consumes":"" ) ]); + push(@rows, [ '', (@rows ? "=> " : '').($extra ? "$extra " : ''). ($scheme ? "$scheme: ":'')."/${endpoint_arg_info}". ($consumes ? " :$consumes":"" ) ]); my @display_parts = map { $_ =~s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; decode_utf8 $_ } @parts; $rows[0][0] = join('/', '', @display_parts) || '/'; $paths->row(@$_) for @rows; @@ -247,6 +260,8 @@ sub recurse_match { } my @try_actions = @{$children->{$try_part}}; TRY_ACTION: foreach my $action (@try_actions) { + + if (my $capture_attr = $action->attributes->{CaptureArgs}) { my $capture_count = $action->number_of_captures|| 0; @@ -290,6 +305,7 @@ sub recurse_match { next TRY_ACTION unless $action->match($c); } my $args_attr = $action->attributes->{Args}->[0]; + my $args_count = $action->comparable_arg_number; my @pathparts = split /\//, $action->attributes->{PathPart}->[0]; # No best action currently # OR This one matches with fewer parts left than the current best action, @@ -297,7 +313,6 @@ sub recurse_match { # OR No parts and this expects 0 # The current best action might also be Args(0), # but we couldn't chose between then anyway so we'll take the last seen - if ( !$best_action || @parts < @{$best_action->{parts}} || @@ -305,12 +320,12 @@ sub recurse_match { !@parts && defined($args_attr) && ( - $args_attr eq "0" && + $args_count eq "0" && ( ($c->config->{use_chained_args_0_special_case}||0) || ( - exists($best_action->{args_attr}) && defined($best_action->{args_attr}) ? - ($best_action->{args_attr} ne 0) : 1 + exists($best_action->{args_count}) && defined($best_action->{args_count}) ? + ($best_action->{args_count} ne 0) : 1 ) ) ) @@ -320,7 +335,7 @@ sub recurse_match { actions => [ $action ], captures=> [], parts => \@parts, - args_attr => $args_attr, + args_count => $args_count, n_pathparts => scalar(@pathparts), }; } @@ -687,7 +702,7 @@ controller. For Example: # in MyApp::Controller::Foo sub bar : Chained CaptureArgs(1) { ... } - # in MyApp::Controller::Foo::Moo + # in MyApp::Controller::Foo::Bar sub bar : ChainedParent Args(1) { ... } This builds a chain like C. @@ -700,7 +715,7 @@ parts of the path (separated by C) this action wants to capture as its arguments. If it doesn't expect any, just specify C<:CaptureArgs(0)>. The captures get passed to the action's C<@_> right after the context, but you can also find them as array references in -C<$c-Erequest-Ecaptures-E[$level]>. The C<$level> is the +C<< $c->request->captures->[$level] >>. The C<$level> is the level of the action in the chain that captured the parts of the path. An action that is part of a chain (that is, one that has a C<:Chained> @@ -727,6 +742,10 @@ custom type constraints and import them into the controller namespace: sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { } +If you use a reference type constraint in CaptureArgs, it must be a type +like Tuple in L that allows us to determine the number of +args to match. Otherwise this will raise an error during startup. + See L for more. =item Args @@ -745,7 +764,10 @@ of path parts after the endpoint. Just as with C<:CaptureArgs>, the arguments get passed to the action in C<@_> after the context object. They can also be reached through -C<$c-Erequest-Earguments>. +C<< $c->request->arguments >>. + +You should see 'Args' in L for more details on using +type constraints in your Args declarations. =back