加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 确定Moose属性和方法的继承地点?

发布时间:2020-12-16 06:28:15 所属栏目:大数据 来源:网络整理
导读:我经常在我的工作地点处理一个庞大的,没有很好记录的,面向对象的Perl回购.在维护代码的同时,我经常需要跟踪从其他类继承的内容,以便我能够理解他们正在做什么.例如,我需要弄清楚$self-神秘是什么以及它在做什么: package Foo::Bar;use Moose;use Method::Si
我经常在我的工作地点处理一个庞大的,没有很好记录的,面向对象的Perl回购.在维护代码的同时,我经常需要跟踪从其他类继承的内容,以便我能够理解他们正在做什么.例如,我需要弄清楚$self->神秘是什么以及它在做什么:

package Foo::Bar;
use Moose;
use Method::Signatures;
use Foo::Bar::Element;
use Foo::Bar::Function;
use base qw (Baz::Foo::Bar);

method do_stuff ($some_arg) {
    # mystery is not defined in Foo::Bar
    my $mystery = $self->mystery;
    $mystery->another_mystery($some_arg);
}

我经常发现自己花费太多时间来追踪父类.所以我的问题是,有一个简单的方法让我弄清楚$self->神秘来自哪里?或者换句话说,我需要找到声明神秘的地方.

通过“简单的方法”,我并不是说使用ack或grep来搜索文件.我希望有一些我可以安装和使用的调试模块,这可以帮助我一些见解.

谢谢.

解决方法

感谢Standard Perl. . . come_from方法!

你不需要下载任何特殊的工具或模块,更不用说一些巨大的IDE,因为你的未记录的类结构已经变得太复杂,只有人类才能理解而没有笨重的IDE.

为什么不?简单:标准Perl包含您获得所需答案所需的一切.找出问题来源的简单方法是使用非常有用的come_from方法:

$origin        = $self->comes_from("mystery");
$secret_origin = $self->comes_from("another_mystery");
$birthplace    = Some::Class->comes_from("method_name");

这将返回该方法将解析的子例程的原始名称.如您所见,come_from既可以作为对象方法,也可以作为类方法,就像can和isa一样.

请注意,当我说出它解析为的子例程的名称时,我指的是最初创建子例程的位置,在任何导入或继承之前.例如,这段代码:

use v5.10.1;
use Path::Router;
my($what,$method) = qw(Path::Router dump);
say "$what->$method is really ",$what->comes_from($method);

打印出来:

Path::Router->dump is really Moose::Object::dump

类似的电话也会发现:

Net::SMTP->mail     is really Net::SMTP::mail
Net::SMTP->status   is really Net::Cmd::status
Net::SMTP->error    is really IO::Handle::error

它也适用于普通的ole子程序:

SQL::Translator::Parser::Storable->normalize_name 
 is really SQL::Translator::Utils::normalize_name

可爱的come_from方法并不是完全内置的,尽管它不需要标准Perl之外的任何东西.为了使您和您的所有类和对象可以访问它,只需在某处添加这些代码 – 您真正喜欢的任何地方:)

sub UNIVERSAL::comes_from($$) {
    require B;
    my($invocant,$invoke) = @_;
    my $coderef  = $invocant->can($invoke) || return;
    my $cv       = B::svref_2object($coderef);
    return unless $cv->isa("B::CV");            
    my $gv       = $cv->GV;
    return if $gv->isa("B::SPECIAL");
    my $subname  = $gv->NAME;
    my $packname = $gv->STASH->NAME;
    return $packname . "::" . $subname;
}

通过声明作为UNIVERSAL子,现在每个人都可以使用它,就像他们使用can和isa一样.请享用!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读