I have been excited about OO programming in Perl thanks to MooseX::Declare but I have never especially liked its performance hit and its cryptic warnings. It turns out that much of this problem is due to MooseX::Method::Signatures, which is used under the hood.
Many moons ago, I was curious about Moose and MooseX::Declare and I posted a question on StackOverflow. Venerable Perl guy Schwern then posted as a comment, that Method::Signatures was better than MooseX::Method::Signatures, and that there was a mod in the works to use it with MX::D.
Recently I have been working on a side-project (non-sciency) which lent itself to an OO design and so I chose MX::D as I often do, but the warning messages I was getting were killing me! I remembered the SO exchange and decided to look for that mod. Turns out it isn’t so much a mod(ification, read: patch) as an extra module, Method::Signatues::Modifiers, which overrides MX::M::S with its own magic when loaded. So I decided to give it a whirl. Here is a test:
use MooseX::Declare;
#use Method::Signatures::Modifiers;
class MyTest {
method do_something ( Ref $thingy ) {
print "Hello World";
}
}
my $obj = MyTest->new();
$obj->do_something( 1 ); # called with incorrect type
Without M::S::M (commented out) the error you get is the totally unreadable:
Validation failed for 'Tuple[Tuple[Object,Ref],Dict[]]' with value "[ [ MyTest=HASH(0x20fa7d0), 1 ], { } ], Internal Validation Error is: \n [+] Validation failed for 'Tuple[Object,Ref]' with value "[ MyTest{ }, 1 ]"\n [+] Validation failed for 'Ref' with value 1" at /home/joel/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/MooseX/Method/Signatures/Meta/Method.pm line 435
MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0x20faa28)', 'ARRAY(0x20dce30)') called at /home/joel/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/MooseX/Method/Signatures/Meta/Method.pm line 151
MyTest::do_something('MyTest=HASH(0x20fa7d0)', 1) called at test.pl line 13
however WITH M::S::M (not commented) you get the far more pleasant and useful:
In call to MyTest::do_something(), the 'thingy' parameter ("1") is not of type Ref at test.pl line 13.
In the documentation, the authors (including Schwern, and Barefoot) note that M::S::M is not perfectly a drop-in replacement for MX::M::S, however the differences they note, I almost never use. So be aware, but don’t let that stop you from switching, you’ll be glad you did.
I haven’t done any compile timing tests, but Schwern seemed convinced that this would be improved too. Doesn’t matter, having useful error messages back is well worth the extra dependency and keystrokes.