Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中检测重写的方法_Perl_Oop_Methods_Overriding - Fatal编程技术网

在Perl中检测重写的方法

在Perl中检测重写的方法,perl,oop,methods,overriding,Perl,Oop,Methods,Overriding,上周,我两次被意外重写子类中的方法所咬。虽然我不喜欢继承,但我们(ab)在工作中的应用程序中使用它。我想做的是提供一些声明性语法来声明方法正在重写父方法。大概是这样的: use Attribute::Override; use parent 'Some::Class'; sub foo : override { ... } # fails if it doesn't override sub bar { ... } # fails if it does override

上周,我两次被意外重写子类中的方法所咬。虽然我不喜欢继承,但我们(ab)在工作中的应用程序中使用它。我想做的是提供一些声明性语法来声明方法正在重写父方法。大概是这样的:

use Attribute::Override;

use parent 'Some::Class';

sub foo : override { ... } # fails if it doesn't override
sub bar { ... }            # fails if it does override
这里有几个问题。首先,如果方法加载以某种方式延迟(例如,通过自动加载加载的方法或稍后安装在符号表中的方法),则不会检测到这些方法

在继承树上行走也可能会付出同样的代价。我用它来实现这一点,但它并不真正适合运行代码。我可以遍历继承树,简单地匹配在适当的符号表中有定义的代码槽的位置,这会更快,但是如果方法缓存无效,如果我缓存这些结果,这会中断

所以我有两个问题:这是一个合理的方法吗?是否有一个钩子允许我检查方法缓存是否已更改?(在“perldoc perlobj”中搜索“cache”)


当然,这不应该破坏生产代码,我只考虑在测试线束环境变量处于活动状态时让它失败或发出警告(如果生产代码出于某种原因设置测试线束环境变量,则使用显式环境变量强制它处于非活动状态)。

强制执行此操作的一种方法:

package Base;
...
sub new {
    my $class = shift;
    ...
    check_overrides( $class );
    ...
}

sub check_overrides {
    my $class = shift;
    for my $method ( @unoverridable ) {
        die "horribly" if __PACKAGE__->can( $method ) != $class->can( $method );
    }
}
记录检查覆盖可能会有所帮助

如果在某些情况下需要豁免,请使用备用方法名和 让基类调用:

package Base;
...
my @unoverridable = 'DESTROY';
sub destroy {}
sub DESTROY {
    my $self = shift;
    # do essential stuff
    ...
    $self->destroy();
}