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

Buddy Burden barefootcoder at gmail.com
Fri Feb 25 01:34:08 GMT 2011


Michael,

>> 1) In MS's parse_func, while looping through the individual params, we
>> add a call such as:
>>
>>     $proto = $self->parse_extra($proto, $sig);
>>
>> In MS itself, this would just be an empty func.  But subclasses could
>> use this to parse out any extra features they want.  They would remove
>> whatever they parse from $proto (that's why it needs to be returned),
>> and add whatever bits they wanted to $sig (e.g. $sig->{type}).
>
> Yeah, ok, sensible.
>
> But type syntax was easy to add, so I added it.

Ah, okay cool.  You didn't have to do all that, you know ... I was
perfectly willing to send you patches for that stuff.  But, since you
did ... thank you! :D

> I'm wary of inject_extra() because it seems to encourage hacking on the code
> MS has generated rather than just adding their own.  This is dangerous.

Well, potentially, yes.  I was just imagining that there might be some
cases where you might want to replace code instead of adding to it ...
for instance, one might want to replace the whole kit and kaboodle
with a call to MXPV's validated_list or somesuch.  So I thought it
might be nice to allow for that.  But if you don't like it, that's
cool by me.  It won't impact anything I personally want to do,
certainly.

> Instead, I turned inject_for_sig() into a method.  I think overriding
> inject_for_sig() gives you all the control you need.

Fair enough.

> Type checking on the invocant is what made MXMS the speed demon it is today. :P

Heh.  Yeah, I noticed your comment in the MXMS bug, but, really,
there's got to be _something_ else going on, doesn't there?  The
performance is _so_ much worse that I just can't conceive it's only
because of that.

But I personally agree with you _mostly_ that you usually don't want
to type check the invocant.  The only thing it's nice for is making
sure class methods aren't called as object methods, and vice-versa.
So I typically declare my class methods as:

    method do_the_thing_with_the_thing (Str $class: Int :$other_param,
Str :$etc)

> You can type check it if you really want to.
>
>    sub inject_for_signature {
>        my $self = shift;
>        my $signature = shift;
>        my $code = $self->SUPER::inject_for_signature($signature);
>
>        my $class = ref $self;
>        return "${class}::type_check($signature->{invocant}, __PACKAGE__); ".$code;
>    }

Ah, but, see, that doesn't work for my example above, because you
haven't parsed out the type from the signature.  Also, forgive me if
I'm misreading the code, but wouldn't that try to type check the
invocant before it was declared?

I think it could be done, though, by overriding parse_signature ...
but then I guess you'd have to override inject_from_signature as well.
 Which is not ideal, but I haven't decided how bad I would want such a
thing yet, so I'll think on it a bit more.

> That would be:
>
>    sub inject_for_sig {
>        my $self = shift;
>        my $sig = shift;
>
>        my @code = $self->SUPER::inject_for_sig($sig);
>
>        push @code, "${class}::type_check('$sig->{type}', $sig->{var},
> '$sig->{name}');" if $sig->{type};
>
>        return @code;
>    }

Yes, that works well.

> I've made your life even simpler by adding an empty inject_for_type_check()
> method.  You should just have to override that.
>
>        sub inject_for_type_check {
>            my $self = shift;
>            my $sig = shift;
>
>            my $class = ref $self;
>            return "$class->type_check('$sig->{type}', $sig->{var},
> '$sig->{name}');";
>        }

And that works even better. :-)

> You can find that in the repo.  Let me know how it works out.  It's pretty
> thinly tested.
> https://github.com/schwern/method-signatures/commits/

It looks great to me, although I haven't had a chance to pull it down
and start really hacking on it yet.  The only thing I would want to
add is the parse_extra type of hook (if you have a better name, of
course, I'm all for that), JIC I decide I want to try to implement
does, or type coercions.  Which I would definitely not want to do
right away, because I don't have any code that needs that, but I can
see wanting it down the road.  So I could submit a patch for that if
you're amenable.

Thanx again for taking the time to do this for me.  I know you work on
a lot of modules, so I'm sure your schedule is crazy busy.  I'm sure
people don't say it enough, so allow me to: you're one of those folks
without whom CPAN would be a much impoverished place.  So thanx for
all you do. :-)


            -- Buddy



More information about the Perl5-syntax mailing list