I'm using MooseX::Declare (which uses MooseX::Method::Signatures (which uses Moose::Meta::TypeConstraint )) with long signatures such as in the following example:
use 5.010;
use MooseX::Declare;
class Manager { };
class Server { has 'hdr' => ( is => 'rw' ) };
class Archive {
#.. other methods
method init_archive ( Manager :$mgr!,
Int :$debug,
Str :$user!,
Str :$pass!,
Str :$path!
where {
$_ !~ /:/ and $_ =~ m{^[\\/]}
},
HashRef :$target_args!
where {
($_->{NR} and $_->{SID} and $_->{dt})
or
($_->{NR} and $_->{SID} and $_->{hostn
+ame})
},
Server :$master
where {
defined $_->hdr
}
) {
say "ARCHIVE INITIALISED";
return $self;
}
}
Archive->new->init_archive( user => 'boldra',
pass => 'secret',
path => 'd:\\data\\DYV\\',
# path => '//hostname/d$/data/DYV',
mgr => Manager->new,
target_args => {
NR => '01',
SID => 1,
hostname => 'localhost' },
master => Server->new( { hdr => 1 } )
+ );
If you look closely, you'll see that I'm breaking the constraint on 'path', by supplying what looks like a local windows path, instead of the expected network path.
The problem you see when you run my example, is that the error message is a little too verbose to be useful, and somewhat defeats the purpose of having signatures:
Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types:
+:Structured::Tuple[Object],MooseX::Types::Structured::Dict[mgr,Manage
+r,debug,MooseX::Types::Structured::Optional[Int],user,Str,pass,Str,pa
+th,__ANON__,target_args,__ANON__,master,MooseX::Types::Structured::Op
+tional[__ANON__]]]' failed with value [ [ Archive=HASH(0x2a012a8) ],
+{ master => Server=HASH(0x2a7ce38), mgr => Manager=HASH(0x2a708e0), p
+ass => "secret", path => "d:\data\DYV\", target_args => HASH(0x1aa3ad
+8), user => "boldra" } ], Internal Validation Error is: Validation fa
+iled for 'MooseX::Types::Structured::Dict[mgr,Manager,debug,MooseX::T
+ypes::Structured::Optional[Int],user,Str,pass,Str,path,__ANON__,targe
+t_args,__ANON__,master,MooseX::Types::Structured::Optional[__ANON__]]
+' failed with value { master => Server={ hdr => 1 }, mgr => Manager={
+ }, pass => "secret", path => "d:\data\DYV\", target_args => { NR =>
+ 01, SID => 1, hostname => "localhost" }, user => "boldra" } at /usr/
+lib/perl5/site_perl/5.10/MooseX/Method/Signatures/Meta/Method.pm line
+ 445
MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method
+::Signatures::Meta::Method=HASH(0x2a7cec8)', 'ARRAY(0x29e1788)') call
+ed at /usr/lib/perl5/site_perl/5.10/MooseX/Method/Signatures/Meta/Met
+hod.pm line 145
Archive::init_archive('Archive=HASH(0x2a012a8)', 'user', 'boldra',
+ 'pass', 'secret', 'path', 'd:\data\DYV\', 'mgr', 'Manager=HASH(0x2a7
+08e0)', ...) called at /home/boldra/archive_test.pl line 40
After looking at the source of Moose::Meta::TypeConstraint, it looks like it's equipped to provide quite precise messages (including looking for a
message method on the class type). So here's the questions:
- Am I doing something wrong in my signatures? What would I change in the code above to get a clear message as which argument is wrong and where?
- If this is a shortcoming of MooseX::Method::Signatures, but it's not because of Moose::Meta::TypeConstraint, where should the fix be? The MooseX::Method::Signature doc (BUGS, CAVEATS) suggests that a bug should be raised if the messages are not good. But which module really has the bug?
- Is there perhaps an easier way to get what I'm after (precise error messages on subroutine/method validation) with a different module?
Thanks for reading this far!
(Bart suggested yesterday that I ask this on a Moose forum, but I thought I'd start here. Feel free to post links to other forums, cpanforums.com/dist/moose seems pretty dead)