So does the equivalent static dispatch table.
Hmm... I hadn't tested that. Ok, how about:
c:\@Work\Perl\monks>perl -MData::Dump -le
"use warnings;
use strict;
;;
sub _x_foo { hiya(@_); }
sub _x_bar { hiya(@_); }
;;
my %disp =
map {
my $agent = qq{_x_$_};
$_ => __PACKAGE__->UNIVERSAL::can($agent)
||
die qq{dispatch via unknown agent '$agent'};
}
qw(foo bar BAM)
;
::dd \%disp;
;;
sub hiya { print 'hi from ', (caller(1))[3], qq{ (@_)}; }
;;
$disp{foo}();
$disp{POW}(qw(x y z));
$disp{bar}(99, 88);
"
dispatch via unknown agent '_x_BAM' at -e line 1.
This throws both compile- and run-time exceptions, although I don't like the obscure wording of the run-time error message.
How about putting the whole thing into a lexically scoped package? This allows full control of the composition of the run-time error message, and makes the dispatch hash entirely private. It's also all ready to be moved off to its own module. I can't say I'm fond the Dispatch::me('foo') invocation syntax, but putting this in its own module would give you some more syntax choices.
c:\@Work\Perl\monks>perl -MData::Dump -le
"use warnings;
use strict;
;;
{ package Dispatch;
;;
sub _x_foo { hiya(@_); }
sub _x_bar { hiya(@_); }
;;
my %disp =
map {
my $agent = qq{_x_$_};
$_ => __PACKAGE__->UNIVERSAL::can($agent)
||
die qq{dispatch via unknown agent '$agent'};
}
qw(foo bar BAM)
;
::dd \%disp;
;;
sub me {
my $tag = shift;
;;
die qq{unknown dispatcher '$tag' used}
unless exists $disp{$tag};
;;
return $disp{$tag}(@_);
}
;;
sub hiya { print 'hi from ', (caller(1))[3], qq{ (@_)}; }
}
;;
Dispatch::me('foo');
Dispatch::me('POW', qw(x y z));
Dispatch::me('bar', 99, 88);
"
dispatch via unknown agent '_x_BAM' at -e line 1.
Give a man a fish: <%-{-{-{-<