I found a fascinating feature documented at 
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 
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?


Attachment: 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/

Reply via email to