[Perl5-syntax] Adding Moose type checking to Method::Signatures

Nick Perez nick at nickandperla.net
Wed Feb 23 09:32:48 GMT 2011


Having done the original hacking on making MXD use MXMS internally, I
can tell exactly what and where you need to hack replace MXMS.
Basically, what I did was to make MXMS able to use an external
Devel::Declare context that was already initialized. Then in MXD, when
the method keyword was encountered, parsing was then passed off to MXMS
to actually do the signature parsing, etc. 

You can follow the implementation pretty easily in MXD.

Start with MooseX::Declare::Syntax::Keyword::Class
See that it consumes MooseX::Declare::Syntax::MooseSetup
Look for default_inner (where the inner keywords are setup,
  specifically method). See MooseX::Declare::Syntax::Keyword::Method
See it consumes MooseX::Declare::Syntax::MethodDeclaration
And in there, you can see the context, etc being passed to MXMS.

It is a little twisty in MXD. Blame Florian :) But inside
Syntax::Keyword::Method, you could easily advise the parse method to
hand things off to MS instead.

On Wed, 23 Feb 2011 01:08:40 -0800
Buddy Burden <barefootcoder at gmail.com> wrote:

> Guys,
> 
> (Schwern advised me to post this over here.  If anyone thinks there's
> a better venue, though, just let me know and I'm happy to move the
> discussion.)
> 
> So, I'm looking to get add some type checking into Method::Signatures
> (MS).  Basically, I need to replace MooseX::Method::Signatures (MXMS),
> for several reasons:
> 
> *) performance--see Michael's bug #64643 filed against MXMS
> *) bugs--see bugs #61070 and #63594 filed against MXMS
> *) confusing error messages
> 
> I wish I was smart enough to be able to contribute a patch to MXMS
> that would fix all these things, but, alas, I am not. :)  But what I
> _have_ been able to do is to use MS instead, and just do the type
> checking separately.  First I did this with MooseX::Params::Validate
> (MXPV), which gives me the better performance, no bug with 5.12, and a
> much nicer error message.  Then I scrapped MXPV altogether (since it
> was checking a lot of things that MS was checking for me already), and
> rolled my own using Moose::Util::TypeConstraints (MUTC) directly,
> which gave me even _better_ performance, still no bug with 5.12, and I
> can make my own damn error message. :)
> 
> So now I want to take it to the next step and have all this rolled
> into one, instead of having type checking separately, which is a bit
> clumsy.  To do what I want, I basically have two problems:
> 
> *) I need to figure out a way to use MS with MooseX::Declare (MXD).
> *) I need to figure out a way to extend MS.
> 
> Now, as to the first problem, I suppose as a last resort I could do
> this by telling MS to use a different keyword than "method", but I
> really don't want to do that if I can help it.  In a perfect world,
> I'd be using basically Perl6 syntax for classes and methods, and have
> as little work to do as possible when we decide to upgrade to P6 (one
> day).  I'd really consider it suboptimal if I have to declare my
> methods with "mymethod" or somesuch silliness, but ANAICT MXD doesn't
> use Devel::Declare::MethodInstaller::Simple the way that MS does, so
> I'm not sure how to work around that.  Perhaps extending MXD ... ?
> 
> The second problem seems much easier.  After studying the MS code, I
> think I can just wrap MS::inject_from_signature() and tack on another
> line for each parameter with a type that looks something roughly like:
> 
>     My::Class::get_type($type) &&
> My::Class::get_type($type)->check($value) || croak("Super cool error
> message here");
> 
> where get_type uses MUTC to find or create the proper type constraint.
>  May need a bit of tweaking here and there, but that should be roughly
> it.
> 
> Now, two issues that I wanted some help with.  First, I was
> considering using a syntax for the types in the signatures something
> like this:
> 
>     method doit ( :$foo is Foo, :$bar is Bar )
> 
> instead of the more traditional
> 
>     method doit ( Foo :$foo, Bar :$bar )
> 
> I was thinking of doing it this way because that would allow me to
> sneak by without having to change any of the parsing that MS is
> already doing--it already not only reads the "is whatever" syntax, but
> also reads multiples, so theoretically something like ":$foo is Foo is
> ro" would work as well.  I'm not sure this syntax would be legal in
> P6, but I _think_ it would be, and it seems like a reasonable
> compromise.  Does this seem reasonable to everyone else as well?
> 
> If so, MS does _nearly_ all the work for me.  The parsing is all done
> for me, and the type would just end up being stored in MS's internal
> structs as a trait.  Then I could access that and build some extra
> lines of code to do the type checking.
> 
> My second issue is that, as I mentioned, I would need to wrap
> inject_from_signature.  But it looks to me like I can't override it
> and just call SUPER because it's not actually a method (just a sub).
> And it's not a Moose class, so I can't use "around".  So the only
> thing I've been able to think of is something like:
> 
>     *Method::Signatures::orig_ifs =
> \&Method::Signatures::inject_from_signature;
> *Method::Signatures::inject_from_signature = \&_inject_from_signature;
> 
>     sub _inject_from_signature
>     {
>         my $code = Method::Signatures::orig_ifs(@_);
>         # add more stuff to $code
>         return $code;
>     }
> 
> Again, that's just rough.  But that seems sorta ... well, hacky. :D
> Is that approach kosher, or am I missing something obvious?
> 
> If anyone wants to hear any more details about my situation, just let
> me know, but I figured I wouldn't drown anyone in details unless they
> asked for it. :)  Any thoughts that anyone has on how I should (or
> shouldn't) proceed would be much appreciated.  TIA.
> 
> 
>             -- Buddy
> 
> _______________________________________________
> Perl5-syntax mailing list
> Perl5-syntax at lists.scsys.co.uk
> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/perl5-syntax
> 


-- 

Nicholas Perez
XMPP/Email: nick at nickandperla.net
http://search.cpan.org/~nperez/
http://github.com/nperez



More information about the Perl5-syntax mailing list