实施调度表

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)

它可以工作,但是看起来却很麻烦。如果有人知道更简单的方法,我仍然会对它很感兴趣。另一方面,如果没有更简单的方法,我希望这可以对某人有所帮助。

ike*_*ami 5

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)

所有这四种方法都允许在同一类中定义这些方法。

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

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