I was having difficulty tracking down a problem with a failing subtype in my code - abstracted to the following:
/lib/Test.pm package Test; use Moose; use Moose::Util::TypeConstraints; use Module::Find qw( useall ); # 'use's Test::View::* and returns a list of modules my @AVAILABLE_VIEWS = useall Test::View; subtype 'View' => as 'ClassName'; subtype 'ViewLookup' => as 'HashRef[View]'; # e.g. # HTML::Table => Test::View::HTML::Table # has 'view_lookup' => ( is => 'rw', isa => 'ViewLookup', default => sub { my %lookup = map { substr( $_, length( __PACKAGE__ . '::View::' ) ) => $_ } @AVAILABLE_VIEWS; # $lookup{ NotLoaded } = 'Test::View::NotLoaded'; return \%lookup; } ); 1; lib/Test/View/Text.pm package Test::View::Test; our $VERSION = '0.01'; sub method { 1 } 1; lib/Test/View/HTML/Table.pm package Test::View::HTML::Table; our $VERSION = '0.01'; sub method { 1 } 1; Throws: Attribute (view_lookup) does not pass the type constraint because: Validation failed for 'ViewLookup' failed with value HASH(0x123aa880) at lib/Moose/Meta/Class.pm line 193 It took a while to track for me to track down the source of my stupidity as it wasn't entirely clear to me where the source of the problem was given the error that Moose threw (it seems obvious now, but in my defence the original code was more complex than the abstract sample above). It turns out I had made a typo in the package declaration (package Test::View::*Test* rather than package Test::View::*Text*). So I made a stupid typo and Moose did the right thing - who'd have thought? Well that would've been the end of it if I hadn't chanced upon mst's "You're not good enough" presentation this morning ( http://www.shadowcat.co.uk/archive/conference-video/yapc-eu-2008/you-arent-good-enough/). However, since I did - I'm writing to this list in an effort to take advantage of my very Moose noobishness to help fellow Moose noobs. Two things would've helped speed up the process of identifying my own ineptitude: - being told the specific failing test rather than the 'root' subtype (i.e. failing ClassName within ViewLookup rather than a failing ViewLookup) - being told why the ClassName failed (pod does mention it makes "complex tests") I haven't looked at the former - but here's a very tentative suggestion to help with the latter - provides a warning before failing the ClassName constraint. +++ lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm 2008-11-21 16:38:32.000000000 +0000 @@ -39,7 +39,14 @@ # \*{${main::}{"Foo::"}} == \*main::Foo:: my $pack = \*::; + my $pack_name; foreach my $part (split('::', $_[0])) { + $pack_name .= ($pack_name ? '::' : '') . $part; + if ( !exists ${$$pack}{"${part}::"} ) { + warn "[warn] ClassName constraint failed for ($_[0])\n". + "[warn] - not in symbol table (did you \"use $pack_name\"?)\n"; + return 0; + } return 0 unless exists ${$$pack}{"${part}::"}; $pack = \*{${$$pack}{"${part}::"}}; } @@ -55,7 +62,10 @@ next if substr($_, -2, 2) eq '::'; return 1 if defined *{${$$pack}{$_}}{CODE}; } - + + warn "[warn] ClassName constraint failed for ($_[0])\n". + "[warn] - class has no VERSION, ISA or CODE defined (typo in package statement?)\n"; + # fail return 0; } Now produces: [warn] ClassName constraint failed for (Test::View::Text) [warn] - class has no VERSION, ISA or CODE defined (typo in package statement?) Attribute (view_lookup) does not pass the type constraint because: Validation failed for 'ViewLookup' failed with value HASH(0xb2a4e90) at lib/Moose/Meta/Class.pm line 193 And if you fix the typo an uncomment the 'Unloaded' line, you get: [warn] ClassName constraint failed for (Test::View::NotLoaded) [warn] - not in symbol table (did you "use Test::View::NotLoaded"?) Attribute (view_lookup) does not pass the type constraint because: Validation failed for 'ViewLookup' failed with value HASH(0x7337ac0) at lib/Moose/Meta/Class.pm line 193 I appreciate that not everyone wants to have those warnings thrown to STDERR but since Moose::Util::TypeConstraints::OptimizedConstraints::ClassName returns 0 or 1 rather than raises exceptions I wasn't sure what was best (is there a global Moose warning/logging policy?) Cheers, Ian -- Dr Ian Sillitoe CATH Team -- http://cathdb.info