Well, I think the use I put them to is awesome, but it's part of an IRC interface to something, so there's sort of a maximum cap on awesomeness.
Anyway, here's some slightly simplified code (using MooseX::POE):
my @MSG_PATTERNS = ( qr/item\s+(?-?\d+)\s*,\s*(? -?\d+)\s*/ => 'item_report', qr/grid/ => 'grid_summary', ); event irc_public => sub { my ($self, $kernel, $nick, $msg) = @_[OBJECT, KERNEL, ARG0, ARG2]; for (my $i = 0; $i < @MSG_PATTERNS; $i += 2) { my ($pattern, $method) = @MSG_PATTERNS[ $i, $i + 1 ]; next unless $msg =~ /\A$pattern\z/; my $result = $self->$method({%+}); if (ref $result) { $self->privmsg($self->channel => $_) for @$result; return; } else { return $self->privmsg($self->channel => "$nick: $result"); } } };
The important points are:
(?<x>-?\d+)
{ %+ }
See, if the pattern matches, all the named captures end up in the magic
variable %+
. That means that after this line:
"item (3, -1)" =~ qr/item\s+(?-?\d+)\s*,\s*(? -?\d+)\s*/
That variable contains:
(x => 3, y => -1)
Basically, by using named captures, I can allow these rules to set up named arguments for methods! I don't need to futz around with converting from a list of positional matches into anything else. I don't even really need to validate (for this application) because I've already matched them against a validating regular expression. I know this is a very simple application of named captures, but the amount to which it simplified this code is amazing. It turned a tedious three step process (extract, translate, dispatch) into an elegant two step process, eliminating translation.
I look forward to future applications of 5.10's fun new features.