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 asfoo(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.
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":
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).
So far I've always used
package Foo { method meth($arg) { ... } }
.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.