当前位置:  开发笔记 > 编程语言 > 正文

检测Perl中的重写方法

如何解决《检测Perl中的重写方法》经验,为你挑选了1个好方法。

上周,我在一个子类中意外地重写方法时被咬了两次.虽然我不是继承的粉丝,但我们(ab)在我们的应用程序中使用它.我想要做的是提供一些声明性语法来声明方法覆盖父方法.像这样的东西:

use Attribute::Override;

use parent 'Some::Class';

sub foo : override { ... } # fails if it doesn't override
sub bar { ... }            # fails if it does override

这里有几个问题.首先,如果方法加载以某种方式延迟(例如,通过AUTOLOAD加载的方法或稍后安装在符号表中的方法),则不会检测这些方法.

走继承树也可能同样昂贵.我用Class :: Sniff做这个,但它不适合运行代码.我可以遍历继承树并简单地匹配适当的符号表中定义的CODE插槽的位置,并且会更快,但如果方法缓存无效,那么如果我要缓存这些结果,那将会中断.

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

当然,这不应该破坏生产代码,我只考虑让它失败或警告TEST_HARNESS环境变量是否处于活动状态(并且有一个显式环境变量来强制它处于非活动状态,如果生产代码是设置TEST_HARNESS由于某种原因的环境变量).



1> ysth..:

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

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 );
    }
}

check_overrides的memoization可能会有所帮助.

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

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

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有