I found a fascinating feature documented at https://metacpan.org/pod/Catalyst::Controller#Args and https://metacpan.org/dist/Catalyst-Runtime/view/lib/Catalyst/RouteMatching.pod#Type-Constraints-in-Args-and-Capture-Args where you can provide a Type::Tiny or other constraint object to Args() or CaptureArgs() instead of specifying the number of arguments to capture as an integer.
However, when I tried it out, I found that even though the documentation and the Catalyst code (in Catalyst::Action resolve_type_constraint()) make it clear that a type object is expected, what is actually received is a string. Looking deeper, it appears that https://metacpan.org/pod/MooseX::MethodAttributes is used to retrieve the parameters provided to Args(), and its documentation shows that only a string will be passed through. From the Catalyst documentation, it seems like it was possible at one time to pass constraint objects to Args(). I'm not sure at what point it stopped working, or if it still works, and I need to do something differently to enable it. package MyApp::Controller::MyController; use Moose; use MooseX::MethodAttributes; use Types::Standard qw(Int); use namespace::autoclean; sub view : PathPart('view') Args(Int) { my ( $self, $c ) = @_; $c->stash->{template} = 'foo.tt'; $c->forward( 'MyApp::View::TT' ); } When I add some debugging to resolve_type_constraint() in Catalyst::Action, I find that what is received is not an object, even though we check to see if it is an object. The code that evals the package and tries to instantiate the type object also does not appear to be successful. sub resolve_type_constraint { my ($self, $name) = @_; if(defined($name) && blessed($name) && $name->can('check')) { # Its already a TC, good to go. warn "$name is a type constraint\n"; return $name; } warn "$name is " . (defined($name) ? '' : 'NOT') . " defined\n"; warn "$name is " . (blessed($name) ? '' : 'NOT') . " blessed\n"; warn "$name can " . ($name->can('check') ? '' : 'NOT') . " check\n"; # This is broken for when there is more than one constraint if($name=~m/::/) { eval "use Type::Registry; 1" || die "Can't resolve type constraint $name without installing Type::Tiny"; my $tc = Type::Registry->new->foreign_lookup($name); return defined $tc ? $tc : die "'$name' not a full namespace type constraint in ${\$self->private_path}"; } my @tc = grep { defined $_ } (eval("package ${\$self->class}; $name")); warn "$name eval'ed within " . $self->class . " becomes:" . join(', ', map { defined($_) ? "'$_'" : undef } @tc) . "\n"; ... } The output I get is: Int is defined Int is NOT blessed Int can NOT check Int eval'ed within MyApp::Controller::MyController becomes: with no values displayed. I'd really like to be able to use this functionality. Any suggestions for what I might try? -kolibrie
signature.asc
Description: PGP signature
_______________________________________________ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/