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

Reply via email to