Cool things you can do with Perl 5.14

Perl 5.12.0 introduced pluggable keywords. This feature lets a module author extend Perl by defining custom keywords, at least as long as that module author knows XS and how to construct OP trees manually.

Perl 5.14.0 added many functions to the API that make custom keywords worthwhile (especially the ability to invoke the Perl parser recursively in order to parse a custom syntax with embedded Perl fragments).

So what can this be used for? In the following, I'm going to show you three modules I've written that make heavy use of custom keywords.

Quote::Code - quoted strings with arbitrary code interpolation

This module adds a new qc quoting operator similar to q and qq. It gives you strings (as usual) but with the ability to interpolate arbitrary expressions (such as method calls!) by wrapping them in { ... }:

print qc!2 + 2 = {2 + 2}\n!;

It also defines qc_to for heredocs with Ruby-esque #{ ... } interpolation:

my $msg = qc_to <<'EOF';
\o/ His power level is #{$user->level + 1}! \o/
EOF

Switch::Plain - a simple switch statement for Perl

This module exists because I wanted something a lot less magical/crazy than Switch or given/when.

It provides two keywords, sswitch and nswitch, for string and numeric comparisons, respectively. It doesn't try to do anything "smart" or dynamic, it just compares strings or numbers:

nswitch ($input) {
    case 1: {
        foo();
    }
    case 2: {
        bar();
    }
    case 3: {
        baz();
    }
    default: {
        print "What's this, then?\n";
        return;
    }
}

Function::Parameters - subroutine definitions with parameter lists

This module is the original reason I started looking into pluggable keywords. It extends Perl with the ability to define functions and methods with parameter lists:

fun foo($x, $y, $z) {
    ...
}

method bar($x, $y) {
    # $self automatically defined here
    $self->frobnicate($x, $y);
}

Or at least that's the short version. It optionally also

  • allows for prototypes
  • lets you specify default arguments
  • checks whether your functions were called with the right number of arguments
  • lets you rename $self (e.g. method new($class: %args) { ... })
  • provides named parameters in addition to the positional parameters used above: fun foo(:$x, :$y) {} (callable as foo(y => 1, x => 2))
  • lets you add default attributes to all functions you define (e.g. :method to all methods)

... and a few other things I'm not going to list here.

Conclusion

I think all of the above modules are seriously cool (I know I wrote them, but still!). If you agree, feel free to go ahead and give them a try. And if you find any bugs, please report them at the usual address (report a bug in Quote::Code, report a bug in Switch::Plain report a bug in Function::Parameters).

If you've been looking for a reason to upgrade to Perl 5.14 or 5.16, maybe these modules can help. ☺

And if this has given you ideas for your own keywords, give it a spin. This is powerful stuff.

3 Comments

Function::Parameters is indeed cool! (BTW, I tried 'use Function::Parameters => {sub=>"function"}' and it still works.)

Now I can write OO code like "a normal person":

class Foo;
method meth($arg) { ... }

The only thing missing is support for the class keyword. What module would you recommend for that? I prefer something that can work without the Moose family. An added niceity would be to provide a nicer syntax for class attributes (something more Perl6-ish, perhaps).

p5-mop (planned for Perl core in some future version, perhaps 5.20; currently on GitHub, but not on CPAN yet) seems to fit your description.

Here's some documentation on the syntax.

Leave a comment

About mauke

user-pic I blog about Perl.