2014-11-20 50 views
2

我修改加載測試框架前使用27個模塊一個相當大的單元測試源:跟蹤導入的子程序的

use Test::Most; 

當腳本達到這條線,它輸出以下警告:

mytest.t ........... Subroutine main::explain redefined at mytest.t line 84. 

現在我可以隱藏重新定義的消息,只需在調用使用前定義子例程即可。

BEGIN { 
    undef *explain; # Method imported somewhere before. Hide the redefine messages 
} 

use Test::Most; 

但是,我想確定哪個模塊正在導入其他版本的解釋。

可以使用消除過程,只是註釋掉一切,直到我得到警告,但如果有更直接的路線來確定源,會很好。

+1

也許HTTP:// WWW。 perlmonks.org/?node_id=1054312? – toolic 2014-11-20 18:33:47

回答

2

在給出警告的行之前插入use Devel::Peek qw(); BEGIN { Devel::Peek::Dump(\&foo); }會告訴你哪個包(COMP_STASH)和文件名(FILE)。

一個解決方案,也讓你的行號是可能的。該函數的操作碼樹可以走直到找到nextstate(這可能是該樹的第一個操作)。文件名和行號可以從操作中提取。 nextstate ops設置運行時警告發出的文件和行號。

注:

  • #line指令將影響這兩種解決方案。

  • 如果一個模塊導出一個導入的子文件,兩個解決方案都會給出原始包和源文件,而不是中介。

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 

(線爲子的結束,而不是開始)