Hi John, Thanks for looking into this. The MooseX::Types version was one of the things I checked (I'm already at 0.08).
I'm happy to try and provide more info if that would help get a test case together (after Stevn's suggestions I've fixed my code now, however I'm sure I can break it again). Also happy to have a pop at a doc patch once I get my head around it a bit better. Cheers, Ian 2009/1/30 John Napiorkowski <jjn1...@yahoo.com> > Hey, based on your dumps, I'm not sure you are on the latest MX:Types and > all. Could you check that so that I can start to look through this and see > if there are any bugs I can create a test case out of? Thanks! > > john > > > > ----- Original Message ---- > From: Stevan Little <stevan.lit...@iinteractive.com> > To: i...@sillit.com > Cc: moose@perl.org > Sent: Thursday, January 29, 2009 1:13:03 PM > Subject: Re: MooseX::Types : subtype/coerce not found in Roles > (hand_optimized_type_constraint?) > > I tend to do the following: > > - make a MyApp::Types package that handles *all* custom type > definitions and type coercions > - make all other packages load MyApp::Types (even if they dont need > it, because their deps might need it) > > Then as far as circular refs are concerned, they are tricky and each > case is a little different. The key is to map out what you need and > the force things to load in that order (this is where the global > MyApp::Types can be really handy). > > Also, find_type_constraint is your friend, it is exported from > Moose::Util::TypeConstraints and can basically be used to detect if > the type already exists or not. Something like: > > if (find_type_constraint('Foo')) { > # do something wiht the Foo type here, like add a coercion > } > > Of course the ideal situation is that you break your circular refs > instead, but sometimes that is just not possible. > > - Stevan > > On Jan 29, 2009, at 11:59 AM, i...@sillit.com wrote: > > > Stevan, > > > > Many thanks for getting back so quickly - that sounds exactly the sort > > of thing that must be happening. > > > > Before I dive in - could I ask what the recommended best practice for > > avoiding circular "use" cases is (if any)? I've generally tried to > > "use" all the modules required by the package to keep each package as > > independent as possible without loading everything unneccessarily. Or > > am I missing something? > > > > Cheers > > > > Ian > > > > On 29/01/2009, Stevan Little <stevan.lit...@iinteractive.com> wrote: > >> Ian, > >> > >> Types can sometimes be very sensitive to load order since they are > >> really done at runtime (it is the runtime immediately following > >> compile time, but still runtime). Based on your description I think > >> you are getting bitten by the auto-creation of types (if Moose > >> doesn't > >> know the type it makes it into a Object subtype that isa(<name of > >> type>)). > >> > >> I would check to make sure that you do not have any circular > >> dependencies in how you load your modules, Perl will handle these > >> fine, but Moose types will be sensitive to the order in which the > >> circle is traversed. > >> > >> - Stevan > >> > >> On Jan 29, 2009, at 6:54 AM, Ian Sillitoe wrote: > >> > >>> Hello, > >>> > >>> I have a problem with subtype/coercions (MooseX::Types library) that > >>> I've > >>> spent ages trying to understand, then ages trying abstract into a > >>> simple > >>> test case but all simple cases seem to work as expected but just not > >>> in my > >>> larger code base. I was hoping that if I put the symptoms up someone > >>> may > >>> spot what is going on and put me out of my misery (or at least point > >>> me to > >>> where I should continue my digging). > >>> > >>> Please excuse any typos in the (incomplete) example code below. I > >>> have coded > >>> up a full version of this simple scenario and I can't replicate the > >>> error > >>> I'm getting in my real code base anyway - so this is meant purely > >>> for > >>> illustration. > >>> > >>> # Types library > >>> package My::Types; > >>> use Moose; > >>> use MooseX::Types -declare [qw( Version DomainID )]; > >>> use My::Version; > >>> > >>> subtype 'Version', > >>> as 'Object', > >>> where { $_->isa( 'My::Version' ) }; > >>> > >>> coerce 'Version', > >>> from 'Str', > >>> via { My::Version::init_from_string( $_ ) }; > >>> > >>> subtype 'ObjectID', > >>> as 'Str'; > >>> > >>> # Role to associate versions with objects > >>> package My::Role::Verisoned; > >>> use Moose::Role; > >>> use My::Types qw(Version); > >>> has 'version' => (is => 'rw', isa => 'Version', coerce => 1); > >>> > >>> # Versioned Object1 > >>> package My::Object1; > >>> use Moose; > >>> with 'My::Role::Versioned'; > >>> > >>> # Versioned Object2 > >>> package My::Object2; > >>> use Moose; > >>> use My::Types qw( DomainID ); > >>> use My::Object1; > >>> with 'My::Role::Versioned'; > >>> > >>> has 'domain_id' => ( is => 'rw', isa => 'DomainID' ); > >>> > >>> sub get_object1 { > >>> my $self = shift; > >>> return My::Object1->new( version => $self->version ); > >>> } > >>> > >>> In this simple case, the subtype/coerce works as expected in both > >>> objects > >>> (the type constaint of the 'version' attribute is the identical) > >>> > >>> $o2 = My::Object2->new( version => '3.2' ); > >>> $o1 = $o2->get_object1; > >>> > >>> warn "Object1: " . > >>> My::Object1->meta->get_attribute_map->{version}->{type_constraint}- > >>>> dump; > >>> warn "Object2: " . > >>> My::Object2->meta->get_attribute_map->{version}->{type_constraint}- > >>>> dump; > >>> > >>> Object1: $VAR1 = bless( { > >>> 'compiled_type_constraint' => 'CODE(0xa41e310)', > >>> 'parent' => 'My::Version', > >>> 'coercion' => > >>> 'Moose::Meta::TypeCoercion=HASH(0xa991c70)', > >>> 'name' => 'Version', > >>> 'constraint' => 'CODE(0x9eb4600)', > >>> 'package_defined_in' => 'My::Types' > >>> }, 'Moose::Meta::TypeConstraint' ); > >>> > >>> Object2: $VAR1 = bless( { > >>> 'compiled_type_constraint' => 'CODE(0xa41e310)', > >>> 'parent' => 'My::Version', > >>> 'coercion' => > >>> 'Moose::Meta::TypeCoercion=HASH(0xa991c70)', > >>> 'name' => 'Version', > >>> 'constraint' => 'CODE(0x9eb4600)', > >>> 'package_defined_in' => 'My::Types' > >>> }, 'Moose::Meta::TypeConstraint' ); > >>> > >>> However, in what seems to be a similar scenario in my live code, I > >>> get the > >>> error that the 'version' attribute doesn't pass the type constraint > >>> when > >>> creating an instance of Object1 inside Object2::get_object1 (it no > >>> longer > >>> seems to be aware of the subtype/coercion in My::Types): > >>> > >>> Attribute (version) does not pass the type constraint because: > >>> Validation > >>> failed for 'Version' failed with value > >>> My::Version::V3_2_0=HASH(0x1aea0930) > >>> at .../Moose/Meta/Attribute.pm line 415 > >>> > >>> When I look at the type constraint of the 'version' attribute in > >>> these two > >>> classes they now appear different: > >>> > >>> warn "Object1: " . > >>> My::Object1->meta->get_attribute_map->{version}->{type_constraint}- > >>>> dump; > >>> warn "Object2: " . > >>> My::Object2->meta->get_attribute_map->{version}->{type_constraint}- > >>>> dump; > >>> > >>> Object1: $VAR1 = bless( { > >>> 'compiled_type_constraint' => 'CODE(0x1ae87c00)', > >>> 'parent' => 'Object', > >>> 'hand_optimized_type_constraint' => > >>> $VAR1->{'compiled_type_constraint'}, > >>> 'name' => 'Version', > >>> 'constraint' => 'CODE(0x1a3c4b80)', > >>> 'class' => 'Version' > >>> }, 'Moose::Meta::TypeConstraint::Class' ); > >>> > >>> Object2: $VAR1 = bless( { > >>> 'compiled_type_constraint' => 'CODE(0x1a929c10)', > >>> 'parent' => 'My::Version', > >>> 'coercion' => > >>> 'Moose::Meta::TypeCoercion=HASH(0x1ae9da00)', > >>> 'name' => 'Version', > >>> 'constraint' => 'CODE(0x1a3c4b80)', > >>> 'package_defined_in' => 'My::Types' > >>> }, 'Moose::Meta::TypeConstraint' ); > >>> > >>> > >>> I hope that difference shows what I might be doing wrong or where to > >>> start > >>> looking (parent => 'Object'? hand_optimized_type_constraint?). This > >>> change > >>> appears to be related to which modules have been "use"d -- in my > >>> live code I > >>> can remove this error by *taking out* the equivalent of "use > >>> My::Types" on > >>> Object2. > >>> > >>> Very much appreciate any help/pointers. > >>> > >>> Cheers, > >>> > >>> Ian > >>> > >>> > >>> -- > >>> Ian Sillitoe > >>> CATH Team -- http://cathdb.info > >> > >> > > > > > > -- > > Ian Sillitoe > > CATH Team -- http://cathdb.info > > > > -- Ian Sillitoe CATH Team -- http://cathdb.info