tags:

views:

59

answers:

2

That has been hours i am tracking a Moose::Util::TypeConstraints exceptions, i don't understand where it gets to check a type and tells me that the name is incorrect. I tracked the error to a reduced example to try to locate the problem, and it just shows me that i do not get it.

Did i get to a Moose::Util::TypeConstraints bug ?

aoffice:new alex$ perl -c ../codesnippets/typeconstrainterror.pl 
../codesnippets/typeconstrainterror.pl syntax OK
aoffice:new alex$ perl -d ../codesnippets/typeconstrainterror.pl 
(...)
DB<1> r
Something::File::LocalFile=HASH(0x100d1bfa8) contains invalid characters for a type name. Names can contain alphanumeric character, ":", and "."
 at /opt/local/lib/perl5/vendor_perl/5.10.1/darwin-multi-2level/Moose/Util/TypeConstraints.pm line 508
    Moose::Util::TypeConstraints::_create_type_constraint('Something::File::LocalFile=HASH(0x100d1bfa8)', undef, undef, undef, undef) called at /opt/local/lib/perl5/vendor_perl/5.10.1/darwin-multi-2level/Moose/Util/TypeConstraints.pm line 285
    Moose::Util::TypeConstraints::type('Something::File::LocalFile=HASH(0x100d1bfa8)') called at ../codesnippets/typeconstrainterror.pl line 7
    Something::File::is_slink('Something::File::LocalFile=HASH(0x100d1bfa8)') called at ../codesnippets/typeconstrainterror.pl line 33
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.  

Below, the code that crashes:

package Something::File;
use Moose;
has 'type' =>(is=>'ro', isa=>'Str', writer=>'_set_type' );

sub is_slink {
    my $self = shift;
    return ( $self->type eq 'slink' );
}

no Moose;
__PACKAGE__->meta->make_immutable;
1;


package Something::File::LocalFile;
use Moose;
use Moose::Util::TypeConstraints;

extends 'Something::File';

subtype 'PositiveInt'
     => as 'Int'
     => where { $_ >0 }
     => message { 'Only positive greater than zero integers accepted' };

no Moose;
__PACKAGE__->meta->make_immutable;
1;


my $a = Something::File::LocalFile->new;
# $a->_set_type('slink');
print $a->is_slink ." end\n"; 
+2  A: 

It looks like Moose::Util::TypeConstraints::type is accidentally getting imported into Something::File and clobbering the accessor for your type attribute. Since TypeConstraints' type method expects to get a type name as its first argument, and not an instance of Something::File, it throws that weird error message (after attempting to stringify your instance).

I'm not sure how this would happen with the code sample you pasted, but the backtrace seems pretty unambiguous. Perhaps the code you're running is different from what you pasted, or perhaps I'm just a little bit dense at 3am.

hobbs
Moose::Util::Typeconstraint's `type` function is overriding the `type` accessor methods inherited via `extends`. Using `namespace::autoclean` will fix that.
perigrin
@perigrin aha. What I was too fuzzy to see at 3am yesterday was the inheritance :)
hobbs
+4  A: 

Elevating this from a comment on hobb's answer.

What's happening is that your method name type that is inherited into Something::File::LocalFile via extends 'Something::File'; is colliding with the type function exported by Moose::Util::TypeConstraints.

I believe that if you use namespace::autoclean inside Something::File::LocalFile you'll see this problem go away. Alternatively if you limit the exports from Moose::Util::TypeConstraints to only the functions you need (ie use Moose::Util::TypeConstraints qw(subtype) the problem will also go away.

perigrin
Great, this works, either renaming my attribute 'type' and its accessors, or using namespace::autoclean, though this adds a dependency for my script
You can also get there with: no Moose::Util::TypeConstraints; I think.
perigrin