我目前正在重构一些代码,并尝试删除下面使用的符号引用来根据输入分派(dispatch)函数。
package Parent;
use strict;
use warnings;
sub dispatch{
my ($self, $funcname) = @_;
no strict "refs";
if($self->can($funcname)){
$self->$funcname();
}
else{
$self->default_func();
}
use strict;
}
sub a{
...
}
sub b{
...
}
#...lots more functions...
sub default_func{
..
}
<小时/>
package Child;
use strict;
use warnings;
use Parent;
our @ISA = qw(Parent)
sub c{
..
}
我考虑过使用如下所示的调度表,但这似乎不太理想,因为跟踪所有子类和复制所有涉及的函数涉及相当多的额外维护。
package Parent;
use strict;
use warnings;
{
my $funcs ||= {
a => sub { shift->a },
b => sub { shift->b },
c => sub { shift->c },
#...lots of functions...
DEFAULT => sub {shift->default_func}
}
sub dispatch{
my ($self, $funcname) = @_;
my $func = $funcs->{$funcname} || $funcs->{DEFAULT};
$self->$func();
}
}
此外,我考虑将调度表转变为成员,以便父类也不必知道子类。然后每个子类都会将自己的函数添加到调度表中。最初,我不希望调度表成为成员,因为我只希望它暴露给一个函数,但也许这是不可避免的。但最终,将其转变为成员并不能解决涉及额外样板和维护的问题。
还有更好的办法吗?这看起来比符号引用要做更多的工作。如果额外的工作能让我避免出现棘手的解决方案,我愿意做,但我不确定从这里开始该朝哪个方向发展。
最佳答案
您的原始代码示例在use strict
下工作正常。 $obj->$method(...)
形式不需要符号引用。这是一种广泛使用的技术,被认为是良好的做法。
另请注意,即使您必须不严格
,也无需像示例中那样在函数末尾再次使用严格
。 strict
是一个词法编译指示,因此它的效果无论如何都仅限于其包含范围。
关于perl - 没有符号引用的调度方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19279100/