http://www.perlmonks.org?node_id=398311


in reply to Re^2: A short, "iffy" rant
in thread A short, "iffy" rant

I guess its time to make my standard plug to use Exporter::Dispatch... although this case is probably too simple to warrant the module.

Replies are listed 'Best First'.
Re^4: A short, "iffy" rant
by tilly (Archbishop) on Oct 12, 2004 at 05:25 UTC
    What problem were you trying to address when you wrote this?

    My feeling is that for the effort of creating a new package (likely in its own file), and importing a module, you get to write sub foo {...} rather than foo => sub {...}, - but I don't see the syntax change as mattering much while I do see that overhead as mattering quite a bit.

    Furthermore rather than seeing closures as an unnecessary complication, I see them as an opportunity. You can ignore the fact that you can use closures to fill in the table. But if you need it, you have the ability to use closures to autogenerate large portions of your dispatch table.

    And a further hash advantage - you are allowed names that would not easy or (in some cases) legal in Perl function names.

      What problem were you trying to address when you wrote this?

      Modularity, Maintenance - the usual suspects. Exporter::Dispatch isn't really aimed at dispatch tables of 3 or 4 subs of 1 line a piece - its aimed for use with large dispatch tables. For instance, the last time I used it was on a project with 4 dispatch tables, each having between 10-30 subroutines, with each subroutine varying in length from 10-60 lines.

      As for closing over lexical variables, you can still do that if the subs are in a separate package - you just put the declaration in the same package as the rest of the dispatch table subs are defined!

      But, as for:

      And a further hash advantage - you are allowed names that would not easy or (in some cases) legal in Perl function names.

      What does that buy you? The only time I think I've ever used a dispatch table that had non-word dispatch names was this:

      my %op_table = ( '+' => sub { $_[0] + $_[1] }, '-' => sub { $_[0] - $_[1] }, '*' => sub { $_[0] * $_[1] }, '>' => sub { $_[0] > $_[1] }, '<' => sub { $_[0] < $_[1] }, '=' => sub { $_[0] == $_[1] }, # this is the one oddball; # otherwise i could just eval'ed.. +. '<=' => sub { $_[0] <= $_[1] }, '>=' => sub { $_[0] >= $_[1] }, '!=' => sub { $_[0] != $_[1] }, );

      This was part of a very simple simulator that I wrote for a language that we have compiled down to 68HC11, and the only reason I wrote it this way was so I could use the raw token as the hash key.

        Non-word dispatch names make sense if you want to dispatch on the name of a condition, and the most convenient names that make sense are driven by external data.

        For instance they may be driven off of filenames, which include characters like . and - in the names. For another instance, take a look at Why I like functional programming. Most of the names there are pieces of HTML tags.

        It is a piece of flexibility that you may not need most of the time, but when you do it is a lifesaver.

        As for length, if your dispatch table is so long that you want to put it into another file, nothing stops you from doing so. I think that the ease of doing it is pretty much equivalent with either syntax. If you really want the sub foo {...} syntax, then you can do it by adding a function called "new", and using OO to dynamically do the dispatch.