Вы переосмысливаете проблему.Выясните строку между двумя косыми чертами, затем найдите имя метода (не ссылка) в хэше.Вы можете использовать скалярную переменную в качестве имени метода в Perl;значение становится методом, который вы на самом деле вызываете:
%url_map = (
'foo' => 'foo_method',
);
my( $type ) = $url =~ m|\A/(.*?)/|;
my $method = $url_map{$type} or die '...';
$dh->$method( @args );
Постарайтесь избавиться от любых циклов, в которых большинство итераций для вас бесполезны.:)
мой предыдущий ответ, который мне не нравится, хотя он ближе к проблеме
Вы можете получить ссылку на метод вконкретный объект с can
(если вы сами не реализовали его, чтобы сделать иначе):
my $dh = Stats::Datahandler->new(); ### homebrew module
my %url_map = (
'/(article|blog)/' => $dh->can( 'articleDataHandler' ),
'/video/' => $dh->can( 'nullDataHandler' ),
);
Способ, которым вы вызываете метод и получаете ссылку на результат.Это не то, что вы хотите для отложенного действия.
Теперь, когда у вас есть это, вы вызываете это как обычную разыменование подпрограммы, а не вызов метода.Он уже знает свой объект:
BEGIN {
package Foo;
sub new { bless {}, $_[0] }
sub cat { print "cat is $_[0]!\n"; }
sub dog { print "dog is $_[0]!\n"; }
}
my $foo = Foo->new;
my %hash = (
'cat' => $foo->can( 'cat' ),
'dog' => $foo->can( 'dog' ),
);
my @tries = qw( cat dog catbird dogberg dogberry );
foreach my $try ( @tries ) {
print "Trying $try\n";
foreach my $key ( keys %hash ) {
print "\tTrying $key\n";
if ($try =~ m{$key}) {
$hash{$key}->($try);
last;
}
}
}