New Method::Signatures, now with crazy defaults

schwern on 2008-10-21T09:03:19

The latest release of Method::Signatures contains a big pile of bug fixes and a break through.

The bug fixes mostly relate to the handling of finding the end of the signature. Various edge cases previously broke things like...

# Closing paren on its own line
method foo(
    $arg
)
{
    ...
}

# Closing paren and opening block on the same line method foo( $arg ) { ... }


That's all fixed.

The other awesome part is a break through in how the signature parser works. Previously it was just a pile of regexes doing and simple code like split /\s*,\s*/, $signature which broke on simple defaults like $msg = "Hello, world!". First I figured I could handle it with something like Text::Balanced, but that lead to writing a rudimentary Perl parser (and a pile of Text::Balanced bugs). This violates the "no source filters" principle (and didn't work) so I scrapped that.

Then hdp suggested using PPI. My first reaction was it's not applicable, after all the signature isn't Perl. But PPI is just a tokenizer, and that's what I needed. Something to tokenize my very Perl-like signature syntax. Works like a charm. A very small parser using PPI splits up the signature by walking through the tokens looking for commas while avoiding any child structures. This is very robust and lets you pass in almost anything as a default.

method silly(
    $num    = 42,
    $string = q[Hello, world!],
    $hash   = { this => 42, that => 23 },
    $code   = sub { $num + 4 },
    @nums   = (1,2,3)
)
{
    ...
}


I'm just using PPI for splitting the list of parameters, but it works so well I may replace all the signature parser regexes with PPI.

This clears up the last of the major bugs under my control. The debugger continues to be a show stopper, but I have to wait on Devel::Declare for that.


PPI?

educated_foo on 2008-10-21T16:01:14

I'm not all that excited to see this requiring PPI. It's really just a much better-tested hack rather than a solution, and IIRC (cpandeps is down) it pulls in half the world in dependencies. What happens if you want to get Method::Signatures, or something like it, into core? Default values are nice, but are they worth the complexity?

Re:PPI?

schwern on 2008-10-21T19:36:31

When it goes into core it doesn't go in as a module, it goes in as syntax. No fucking around with PPI, the Perl parser gets patched.

And trust me, PPI is the least terrifying dependency Method::Signatures uses. Its deps are shallow and mundane. It's battle tested (Perl::Critic has been knocking it around for a long time), easy to figure out what the hell its doing and it does what it says on the tin.

Really, you should have seen what I was trying to do with Text::Balanced. That was a swamp and it didn't even half work.

Re:PPI?

ChrisDolan on 2008-10-22T01:58:26

I agree. PPI is solid.