Method::Signatures : Some relief for MooseX::Declare users
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.
As I delve into the deeper Perl magic I like to share what I can.