Perl dispatch tables

From my email archives:

I was reading Higher Order Perl (ISBN 1-55860-701-3) last night at the local coffee shop while my fiancee had her knitting circle meeting when I discovered ‘dispatch tables’. While I have run across them while writing the various chat bots (Net::IRC), I didn’t actually put 2 and 2 together and realize that they were called dispatch tables. Back in North Dakota State University, we called them something else which I don’t remember. lol .. anyways, I quick overview:

Dispatch Tables

File to be read:

VERBOSITY 8

LOGFILE /home/froebeja/log/potatoes_on_steroids.log

CONFIG_FILE /home/froebeja/conf/potatoes_on_steroids.cfg

LOCAL_CONFIG /usr/local/app/sybase/conf/potatoes_on_steroids.cfg


Traditional readConfig() function:

  sub readConfig {
    my ($filename) = shift;
 
    open my ($FH) or return;
    my $config;
 
    while (< $FH>) {
        chomp;
        my ($directive, $rest) = split /\s+/, $_, 2;
 
        if ($directive eq 'VERBOSITY') {
            $config->{VERBOSITY} = $rest;
            ....  do something
        } elsif ($directive eq 'LOGFILE') {
            $config->{LOGFILE} = $rest;
            .... do something
        } elsif ($directive eq 'CONFIG_FILE') {
            $config->{CONFIG_FILE} = $rest;
            .... do something
        } ....
 
    return $config;
}

DISPATCH TABLE implementation

$dispatch_table = {
    VERBOSITY => sub { $VERBOSITY = shift } ,
    LOGFILE => \&config_LOGFILE,
    CONFIGFILE => \&config_CONFIG_LOGFILE,
    LOCAL_CONFIG => \&config_LOCALCONFIG
};
 
sub config_LOGFILE {
    .... do something
}
 
sub readConfig {
    my ($filename, $actions) = @_;
 
    open my($FH), $filename or return;
 
    while (< $FH>) {
        chomp;
        my ($directive, $rest) = split /\s+/, $_, 2;
 
        if (exists $actions->{$directive}) {
            # lookup which procedure to call by reading the 
            $actions->{$directive} ->($rest);
        } else {
            warn "ERROR: Unrecognized config directive on line $. of $filename.\n";
            return;
        }
    }
    return 1;
}
 
readConfig("my.cfg", $dispatch_table);

The real advantage is when dealing with dozens, hundreds or thousands of items where an operation has to be performed. Instead of a massive if/else structure, the problem is nicely broken up into manageable bite sizes. This makes design and maintenance a lot easier.

Thought I would share this little tidbit.

Share Button