Re: MooseX::Types : subtype/coerce not found in Roles (hand_optimized_type_constraint?)

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.