July 2023 Archives

More prototype play: Dispatch::Fu

I was seeing this so much talk about smartmatch or given/when, I decided to experiment with a prototype powered pseudo structure I'd been thinking about. The results were pleasing to me, and I plan on releasing this soon. I could rename it to match/case (versus fu/on), but the huffman in me likes the short (and semi-ambiguous) "keywords". Let me know what you think in the comments below.

I still need to do more unit tests, POD, dist.ini, etc. But it's the closest I could get what I was observing on P5P. And the current implementation is about as fast and tight as I think it could be. I also enjoy using Perl's datatype coercion capabilities via prototypes* quite a bit. It is a very powerful, underutilized, and misunderstood capability that can be used to bring about a lot more ideas via a "keyword" experience (which is the entire point).



The first block computes a static key based on the contents of $bar. This is user defined, the dev gets a single reference to contain all the goods; they are then unpacked and a static key is computed. It's a form of reduction or digest, or to use a buzz word,classification. The key is then used to do an O(1) dispatch of the handler.

NOTE: it inverts and generalizes the application of the regexps in the "case" statements above. In Dispatch::Fu, a "case" (or on) is a static string; That string is determined in the "match" (or fu), so that's where you'd do the checking with regexps.

The following code works and is very fast. A more involved test from the snippet below can viewed here


use strict;
use warnings;
use Dispatch::Fu;    # exports 'fu' and 'on'

my $bar = [qw/1 2 3 4 5/];

fu {
    # here, give a reference $bar of any kind,
    # you compute a static string that is added
    # via the 'on' keyword; result will be
    # 'bucket' + some number in in 0-5

    my $baz = shift;
    return ( scalar @$baz > 5 )
      ? q{bucket5}
      : sprintf qq{bucket%d}, scalar @$baz;
  on bucket0 => sub { print qq{bucket 0\n} },
  on bucket1 => sub { print qq{bucket 1\n} },
  on bucket2 => sub { print qq{bucket 2\n} },
  on bucket3 => sub { print qq{bucket 3\n} },
  on bucket4 => sub { print qq{bucket 4\n} },
  on bucket5 => sub { print qq{bucket 5\n} };

Next step is to roll it into a release for CPAN. I will probably change the name, and for now am considering calling it a collapse (into static key) / on. Feedback welcome.


* Far More Than Everything You've Ever Wanted to Know about Prototypes in Perl.

About Oodler 577

user-pic Mayor of Falvortown