2. Dispatch Tables

条件分岐にDispatch Tableを使うことで

  1. 巨大なif-else文を排除できる。
  2. Additiveにできる(これはSICPに書いていることだけど)

などの利点がある。

あんま使ったこと無いけど、使いかたを覚えればかなり便利そう。

#!/usr/bin/env perl

use strict;
use warnings;

my @stack;
my $actions = {
    '+' => sub { push @stack, pop(@stack) + pop(@stack) },
    '*' => sub { push @stack, pop(@stack) * pop(@stack) },
    '-' => sub { my $s = pop(@stack); push @stack, pop(@stack) - $s },
    '/' => sub { my $s = pop(@stack); push @stack, pop(@stack) / $s },
    'NUMBER' => sub { push @stack, $_[0] },
    '_DEFAULT_' => sub { die "Unrecognized token '$_[0]'; aborting" },
};

my $result = evaluate($ARGV[0], $actions);
print "Result: $result\n";

sub evaluate {
    my ($expr, $actions) = @_;
    my @tokens = split /\s+/, $expr;

    for my $token (@tokens) {
	my $type = '';
	if ($token =~ /^\d+$/) {
	    $type = 'NUMBER';
	}
	
	my $action = $actions->{$type}
	|| $actions->{$token}
	|| $actions->{'_DEFAULT_'};

	$action->($token, $type, $actions);
    }
    return pop(@stack);
}

実行結果

[tomopple]~/Program/perl $ ./calc.pl "2 3 + 4 *"
Result: 20