perl – 确定Moose属性和方法的继承地点?
我经常在我的工作地点处理一个庞大的,没有很好记录的,面向对象的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一样.请享用! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |