我经常在我的工作地点处理一个庞大的,没有很好记录的,面向对象的Perl回购。在维护代码的同时,我经常需要跟踪从其他类继承的内容,以便我能够理解他们正在做什么。例如,我需要弄清楚$self->mystery
是什么以及它在做什么:
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->mystery
来自哪里?或者换句话说,我需要找到声明神秘的地方。
通过"简单方法",我不是指使用ack
或grep
来搜索文件。我希望有一些我可以安装和使用的调试模块,这可以帮助我提供一些见解。
谢谢。
答案 0 :(得分:5)
comes_from
方法!你不需要下载任何特殊的工具或模块,更不用说一些巨大的IDE了,因为没有笨重的IDE,你的未记录的类结构变得太复杂,只有人类才能理解。
为什么不呢?简单:标准Perl包含您需要的一切以获得您正在寻找的答案。找出问题所在的简单方法是使用非常有用的comes_from
方法:
$origin = $self->comes_from("mystery");
$secret_origin = $self->comes_from("another_mystery");
$birthplace = Some::Class->comes_from("method_name");
这将返回该方法将解析的子例程的原始名称。如您所见,comes_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
可爱的comes_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
一样。享受!
答案 1 :(得分:2)
您确定不需要IDE吗?这似乎是你在问什么。 Padre,Eclipse EPIC,Emacs和vim以及许多其他编辑者对您提到的功能提供了一些变体 - 可能比您想要的更简单。如果您有大型项目导航ctags
可以提供帮助 - 通常很容易将其集成到编辑器中,并且您可以使用 regexes BTW来破解配置文件以使其识别一组复杂的源文件。
有一个相关的PERL FAQ entry about IDEs和一个SO问题:What's a good development environment for Perl?。您还需要在开发时使用许多CPAN模块,以便以编程方式查看代码:
您可以看到一个脚本示例,该脚本在SO节点的类中查找方法:Get all methods and/or properties in a given Perl class or module。
您可以使用这些工具来帮助您以一种从shell或调试器内部发现有用的方式在源代码中跳转。 Trepan有一个很好的调试工具简短摘要作为其文档的一部分。一般来说,Data::Dumper
B::
modules B::Xref
,B::Deparse
,等,etc。{调试器和ack
。