Signature introspection

JonathanWorthington on 2009-10-27T17:45:55

One of my Hague Grant tasks was to get a signature introspection interface into the specification and get Rakudo conforming to it. While there may still be some minor tweaks to come, this part is essentially done now. You can read the spec additions in S06.

First off, you can call .signature on any block to get hold of its signature object - an instance of the Signature classs. Calling .params on a Signature object will in turn give you a List of Parameter objects, which describe each of the parameters specified in the signature. We are able to introspect the types, the names, whether the parameter is optional, get a closure that returns any default value and more. Here's an example.

sub example(Int $x, Str $y?) { }
my $sig = &example.signature;
for $sig.params -> $param {
    say "Name: {$param.name}, Type: {$param.type}, Optional: {$param.optional}";
}

This gives the output:

Name: $x, Type: Int(), Optional: 0
Name: $y, Type: Str(), Optional: 1

To make sure that all of the information was really there and accessible, I then went and re-implemented the .perl method on a Signature in Perl 6 in the setting, using the Parameter objects. The new version lacked several of the bugs that the previous version had, which cleared up a few RT tickets. And finally, moritz++ wrote a bunch of spectests for signature introspection, following the new spec.


Cool!

davegaramond on 2009-10-28T02:33:32

This opens up many possibilities like generating codes for form validation/processing, command line "usage", etc all from signatures. Btw, is it possible (or are there plans to make it possible) to embed a description/note to each parameter?

Parameter traits

JonathanWorthington on 2009-10-29T00:32:22

Hi!

Yes, I think people will be able to use this to build some pretty cool stuff, and I look forward to seeing that. :-)

Being able to attach some extra data would be done through parameter traits. I've got all of the pieces to do those, pretty much; just need to plug them together. But it'll look something like...

role note { has $.note }
multi trait_mod:<is>(Parameter $p, note, $message) {
    $p does note($message);
}

After which you'll be able to write:

sub drink($beverage is note('beer is best')) { ... }
say &sub.signature.params[0].note;

Essentially, just mixing a role into the Parameter object. Probably will be working in a couple of weeks or so.

Thanks,

Jonathan