在加载测试框架之前,我修改了一个使用27个模块的相当大的单元测试:
use Test::Most;
当脚本到达此行时,它会输出以下警告:
mytest.t ........... Subroutine main::explain redefined at mytest.t line 84.
现在我可以通过在调用use之前简单地取消定义子例程来隐藏重新定义的消息。
BEGIN {
undef *explain; # Method imported somewhere before. Hide the redefine messages
}
use Test::Most;
但是,我想确定哪个模块正在导入另一个版本的解释。
可以使用消除过程并在我收到警告之前注释掉所有内容,但如果有更直接的路径来确定来源会很好。
答案 0 :(得分:2)
在提供警告的行之前插入use Devel::Peek qw( ); BEGIN { Devel::Peek::Dump(\&foo); }
会告诉您哪个包(COMP_STASH
)和文件名(FILE
)。
也可以为您提供行号的解决方案。可以遍历函数的操作码树,直到找到nextstate
(这可能是树的第一个操作)。可以从op中提取文件名和行号。 nextstate
操作设置运行时警告发出的文件和行号。
注意:
#line
指令会影响两种解决方案。
如果模块导出导入的子模块,则两个解决方案都会提供原始包和原始文件,而不是中间人。
答案 1 :(得分:2)
您可以使用perl的内省工具(称为B):
use B;
my $gv = B::svref_2object(\&explain)->GV;
printf "%s::%s file %s line %s\n", $gv->STASH->NAME, $gv->NAME, $gv->FILE, $gv->LINE;
Test::Most::explain file /usr/share/perl5/Test/Most.pm line 175
(行是sub的结尾,而不是开头)