我正在研究一个非常大的,非常古老的"历史悠久的"代码库.在过去,经常有人在想"哦,我可能需要这个和那个模块,所以我只是把它包括......",后来,人们经常"缓存"模块内的数据("使用ThisAndThat"需要一些几秒钟加载从DB到RAM的几百MB,是的,它真的是一个愚蠢的想法,我们也在努力)因此,通常,我们有一个小模块使用20或30个模块,其中90%是在源本身中完全未使用,并且,由于在几个使用的子模块中"缓存",模块往往需要花费一分钟来加载甚至更多,这当然是不可接受的.
所以,我试图让它做得更好.现在,我的方式是查看所有模块,尽可能地了解它们,然后查看包括它们在内的所有模块,看看它们是否需要.
有没有更简单的方法?我的意思是:有一些函数返回模块所具有的所有子函数
...
return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
Run Code Online (Sandbox Code Playgroud)
那么,有没有简单的方法可以看到哪些是默认导出的,哪些来自哪里,并在其他模块中使用?
一个简单的例子是Data :: Dumper,它几乎包含在每个文件中,甚至,当所有调试警告和打印等等都不在脚本中时.但是模块仍然需要加载Data :: Dumper.
有没有简单的方法来检查?
谢谢!
以下代码可能是您的解决方案的一部分 - 它将显示为每个实例导入的符号use
:
package traceuse;
use strict;
use warnings;
use Devel::Symdump;
sub import {
my $class = shift;
my $module = shift;
my $caller = caller();
my $before = Devel::Symdump->new($caller);
my $args = \@_;
# more robust way of emulating use?
eval "package $caller; require $module; $module\->import(\@\$args)";
my $after = Devel::Symdump->new($caller);
my @added;
my @after_subs = $after->functions;
my %before_subs = map { ($_,1) } $before->functions;
for my $k (@after_subs) {
push(@added, $k) unless $before_subs{$k};
}
if (@added) {
warn "using module $module added: ".join(' ', @added)."\n";
} else {
warn "no new symbols from using module $module\n";
}
}
1;
Run Code Online (Sandbox Code Playgroud)
然后将"use module ..."替换为"use traceuse module ...",您将获得导入的函数列表.
用法示例:
package main;
sub foo { print "debug: foo called with: ".Dumper(\@_)."\n"; }
use traceuse Data::Dumper;
Run Code Online (Sandbox Code Playgroud)
这将输出:
using module Data::Dumper added: main::Dumper
Run Code Online (Sandbox Code Playgroud)
即,您可以确定哪些功能以强大的方式导入.您可以轻松地扩展它以报告导入的标量,数组和哈希变量 - 检查文档Devel::Symdump
.
确定实际使用哪些函数是等式的另一半.为此,您可以使用简单的源代码grep - 即Dumper
出现在模块的源代码中,而不是use
在线上.这取决于您对源代码的了解.
笔记:
可能有一个模块可以执行traceuse所做的事情 - 我没有检查过
可能有更好的方法来模仿另一个包中的"使用"
归档时间: |
|
查看次数: |
1571 次 |
最近记录: |