in reply to Re: Easy dispatch tables. (pointless?)
in thread Easy dispatch tables.

How about this:

use CGI qw(:all); my $op = param('operation'); my $table = create_dptable TestPkg; $table->{$op}->() if exists $table->{$op};

As opposed to this:

use CGI qw(:all); my $op = param('operation'); { no strict 'refs'; TestPkg->$dispatch('Hello!') if defined *{"TestPkg::$dispatch"}{CODE}; }


Or what about this:

my $input = <>; my $table = create_dptable TestPkg; $table->{$_}->($input) foreach (keys $table);

As opposed to this:

my $input = <>; { no strict 'refs'; *{"TestPkg::$_"}{CODE}->($input) foreach( grep { !/^_/ && defined *{"TestPkg::$_"}{CODE} } keys %{*{'TestPkg::'}} ); }

Essentially, the gain of a dispatch table is the gain of all of the advantages and techniques of working with hashes.

Update: Added another example.

Replies are listed 'Best First'.
Re^3: Easy dispatch tables. (still easier)
by Aristotle (Chancellor) on Apr 03, 2003 at 02:54 UTC
    use CGI qw(:all); my $op = param('operation'); TestPkg->$dispatch('Hello!') if UNIVERSAL::can('TestPkg', $dispatch);
    You could also define an AUTOLOAD in TestPkg and forget about it entirely.
    my $input = <>; $_->($input) for map /^_/ ? () : *{$TestPkg::{$_}}{CODE} || (), keys %TestPkg::;
    Or maybe
    my $input = <>; my $sub; !/^_/ && *$sub{CODE} && *$sub{CODE}->($input) while ($_, $sub) = each %TestPkg::;
    Any way you turn it though, I don't see the advantage of
    package Foo; use Dispatch; sub bar { ... } sub baz { ... } package main; my $t = Foo->create_dptable; $t->{bar}->($quux);
    over
    my $t = { bar => sub { ... }, baz => sub { ... }, }; $t->{bar}->($quux);

    If anything, the latter keeps together things that belong together and is quicker to grasp the purpose of.

    Fixed minor errors thanks to jryan

    Makeshifts last the longest.

      Do you really think those 3 counter-examples are really easier to read than the 2-line examples using Dispatch.pm?

      I could mutter stuff about abstraction and orthagonality, but I'm not sure if you'd buy into it. How about another reason: that it makes the concept of dispatch tables easier to create and be less prone to error. Your approaches all take either a high level of perl knowledge, or are simply not as easy to use, or are bulky. Sure, this module doesn't do anything spectacular, and sure, its pretty easy to write equivalant code. However, this module was designed to help abstract and de-couple code, which it does a good job at. So, I'll have to disagree with your opinion that Dispatch.pm is useless. I enjoy using it, at least.

        I agree the second and third are more opaque than your snippets, but that's because there's no function that hides the guts - you could define a Foo::_callables() and then it wouldn't look any more intimidating than your examples (of course that's 90% of what you do, anyway).

        But really, if I need to call a series of functions, I'd put them in a hash or array. And I really think the UNIVERSAL::can example is the simplest solution for that case.

        Which, silly me, can of course be written

        Foo->$bar($baz) if Foo->can($bar);
        and then I think there's really no debate anymore over whether that's simple.

        Makeshifts last the longest.