Perl 实现调度表

Perl 实现调度表,perl,hash,reference,Perl,Hash,Reference,我试图实现一个调度表,它调用Perl模块内的函数。我通常知道如何实现分派表,但当从$self中引用对象方法时,我似乎无法正确实现分派表。也许我在谷歌搜索得不够,但到目前为止,正确的语法还是难以捉摸 我通过调用跟踪了参数,我知道发生了什么——函数引用没有接收到对$self的引用作为其第一个参数。这是我目前在$self中拥有的内容。我相信我把这个抄得很好;如果我犯了一个错误,它没有运行,我道歉 包MyRefHashTest; 严格使用; 使用警告; 次新{ 我的$class=shift; 我的$se

我试图实现一个调度表,它调用Perl模块内的函数。我通常知道如何实现分派表,但当从$self中引用对象方法时,我似乎无法正确实现分派表。也许我在谷歌搜索得不够,但到目前为止,正确的语法还是难以捉摸

我通过调用跟踪了参数,我知道发生了什么——函数引用没有接收到对$self的引用作为其第一个参数。这是我目前在$self中拥有的内容。我相信我把这个抄得很好;如果我犯了一个错误,它没有运行,我道歉

包MyRefHashTest;
严格使用;
使用警告;
次新{
我的$class=shift;
我的$self={
分派=>{
ONE=>\&funcOne,
二=>\&funcTwo,
三=>\&funcThree,
四=>\&funcFour
}
};
祝福$self,$class;
返回$self;
}
亚功能酮{
我的($self,$param)=@;
打印“func1$param\n”;
}
子函数二{
我的($self,$param)=@;
打印“func2$param\n”;
}
次功能三{
我的($self,$param)=@;
打印“func3$param\n”;
}
子函数4{
我的($self,$param)=@;
打印“func4$param\n”;
}
子运行测试{
我的($self,$type)=@;
($self->{DISPATCH}{$type}| | sub{})->(“string”);
}
1.
#要测试:
$test=MyRefHashTest->new;
$test->runTesting(“一”);
$test->runTesting(“两个”);
$test->runTesting(“三”);
$test->runTesting(“四”);
我得到的实际输出是$param在调度表中的函数调用中未定义,而它本不应该被定义。这就是为什么我知道$self的引用不是它们应该在的地方。函数认为$type是$self

我尝试过编辑哈希表引用,使它们看起来像\$self->functionName,但这只会导致$self的编译错误,因为该行没有正确定义

有人能告诉我这个的正确语法吗

谢谢

编辑:经过更多的工作,我终于找到了解决办法。这是一些非常有趣的语法,比我想象的要复杂得多。基本上,我是从内到外构建哈希:

my$self={
DISPATCH=>undef
};
$self->{DISPATCH}={
ONE=>sub{$self->funcOne(@);},
TWO=>sub{$self->funcTwo(@);},
THREE=>sub{$self->funcThree(@);},
FOUR=>sub{$self->funcFour(@);}
};

这是可行的,但这似乎是一个什么样的麻烦很多。如果有人知道一种更简单的方法,我仍然会对此非常感兴趣。另一方面,如果没有更简单的方法,我希望这能帮助一些人。

下面是实现基于方法的分派表的四种方法。随后解释了差异

my %DISPATCH = (
    ONE   => \&funcOne,
    TWO   => \&funcTwo,
    THREE => \&funcThree,
    FOUR  => \&funcFour,
);

sub runTesting {
    my ($self, $type) = @_;
    my $method = $DISPATCH{$type};
    return $self->$method("string");
}

这四种方法都允许在同一个类中定义方法

最后三种方法也允许在超类中定义方法


最后两种方法也允许子类提供或重写该方法。这些是您的最佳选择。

在动态分派方法中传入
$self
如何:

sub runTesting {
    my ($self, $type) = @_;
    ($self->{DISPATCH}{$type} || sub {})->($self,"string");
                                           ^^^^^
}

我认为问题在于,您将这些方法作为普通函数而不是对象方法调用。

Hey@ikegami。我是Perlmonks的holli。我正试图参与其中,但我和这里的人相处得很艰难。帖子被编辑,完美的问题一直被搁置,我刚刚看到你的帖子被否决了。“你是怎么处理的?”霍莉,我的回答中有一个错误。这可能就是它被否决的原因。我会很感激被告知这一点,但谢天谢地,我找到了答案并解决了它。在这里,对问答质量的高度关注往往会有些过头。尽管如此,这是一个非常有用的网站。谢谢你的详细回答(池上!)如果这个答案令人满意,请勾选旁边的标记。谢谢您的回答!
my %DISPATCH = (
    ONE   => 'funcOne',
    TWO   => 'funcTwo',
    THREE => 'funcThree',
    FOUR  => 'funcFour',
);

sub runTesting {
    my ($self, $type) = @_;
    my $method_name = $DISPATCH{$type};
    return $self->$method_name("string");
}
my %DISPATCH = (
    ONE   => sub { shift->funcOne(@_) },
    TWO   => sub { shift->funcTwo(@_) },
    THREE => sub { shift->funcThree(@_) },
    FOUR  => sub { shift->funcFour(@_) },
);

sub runTesting {
    my ($self, $type) = @_;
    my $cb = $DISPATCH{$type};
    return $cb->($self, "string");
}
sub runTesting {
    my ($self, $type) = @_;
    ($self->{DISPATCH}{$type} || sub {})->($self,"string");
                                           ^^^^^
}