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

Buddy Burden barefootcoder at gmail.com
Thu Feb 24 04:54:55 GMT 2011


Michael,

> Okay, I'll think about this some more and see if I figure out how to
> do some of this stuff.

Okay, I thought about it. :)

How about a two-pronged approach:

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}).

2) MS's inject_from_signature changes to be a method.  Then, we add a
line such as:

    @code = $self->inject_extra($signature, @code);

This would be at the bottom, just before turning the lines of code
into a single line.  Again, in MS this would be an empty func.  In the
subclass, you could append code, insert code into the middle, or
_possibly_ even change the code (although that would probably be
discouraged, but it might be necessary for some applications).

I _think_ the only thing you couldn't actually do with this is to
implement type-checking on the invocant, which I know is allowed in P6
syntax ('cause I just saw it in a Synopsis yesterday <s>).  But I
think people can probably live with that.

A super-simple type parser might just do something like:

    sub parse_extra
    {
        my ($self, $proto, $sig) = shift;
        if ($proto =~ s/^(\w+)//)
        {
            $sig->{type} = $1;
        }
        return $proto;
    }

Maybe a bit more error checking, or a more sophisticated regex, but
you see where I'm going.  The corresponding inject might look like:

    sub inject_extra
    {
        my ($self, $signature, @code) = @_;
        my $class = ref $self;
        foreach (@{$signature->{positional}}, @{$signature->{named}})
        {
            # need to pass name just for error messages
            push @code, "${class}::type_check('$_->{type}', $_->{var},
'$_->{name}');" if $sig->{type};
        }
        return @code;
    }

This is a first cut at it, and it's a pretty simple (perhaps
simplistic) design.  Does anyone see any glaring problems with it?


            -- Buddy



More information about the Perl5-syntax mailing list