Jes*_*nni 4 perl hash reference
我正在尝试实现一个调度表,该调度表调用Perl模块内的函数。我知道一般如何实现调度表,但是当从$ self内引用对象方法时,似乎无法正确实现。也许我对Google的搜索还不够,但是到目前为止,正确的语法还难以捉摸。
我已经通过调用跟踪了参数,而且我知道发生了什么事-函数引用没有收到对$ self的引用作为它们的第一个参数。这就是我目前在$ self中拥有的东西。我相信我已正确复制了此内容;如果我犯了一个错误并且它没有运行,我深表歉意。
package MyRefHashTest;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = {
DISPATCH => {
ONE => \&funcOne,
TWO => \&funcTwo,
THREE => \&funcThree,
FOUR => \&funcFour
}
};
bless $self, $class;
return $self;
}
sub funcOne {
my ($self, $param) = @_;
print "func1 $param \n";
}
sub funcTwo {
my ($self, $param) = @_;
print "func2 $param \n";
}
sub funcThree {
my ($self, $param) = @_;
print "func3 $param \n";
}
sub funcFour {
my ($self, $param) = @_;
print "func4 $param \n";
}
sub runTesting {
my ($self, $type) = @_;
($self->{DISPATCH}{$type} || sub {})->("string");
}
1;
# To Test:
$test = MyRefHashTest->new;
$test->runTesting("ONE");
$test->runTesting("TWO");
$test->runTesting("THREE");
$test->runTesting("FOUR");
Run Code Online (Sandbox Code Playgroud)
我得到的实际输出是$ 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(@_); }
};
Run Code Online (Sandbox Code Playgroud)
它可以工作,但是看起来却很麻烦。如果有人知道更简单的方法,我仍然会对它很感兴趣。另一方面,如果没有更简单的方法,我希望这可以对某人有所帮助。
my %DISPATCH = (
ONE => \&funcOne,
TWO => \&funcTwo,
THREE => \&funcThree,
FOUR => \&funcFour,
};
sub runTesting {
my ($self, $type) = @_;
my $method = $DISPATCH{$type};
return $self->$method("string");
}
Run Code Online (Sandbox Code Playgroud)
要么
my %DISPATCH = (
ONE => __PACKAGE__->can('funcOne'),
TWO => __PACKAGE__->can('funcTwo'),
THREE => __PACKAGE__->can('funcThree'),
FOUR => __PACKAGE__->can('funcFour'),
};
sub runTesting {
my ($self, $type) = @_;
my $method = $DISPATCH{$type};
return $self->$method("string");
}
Run Code Online (Sandbox Code Playgroud)
要么
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");
}
Run Code Online (Sandbox Code Playgroud)
要么
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");
}
Run Code Online (Sandbox Code Playgroud)
所有这四种方法都允许在同一类中定义这些方法。
最后三种方法也允许在超类中定义方法。
最后两种方法允许子类也提供或重写该方法。这些是您最好的选择。