目錄

名稱

診斷,splain - 產生詳細的警告診斷

語法

使用 diagnostics 指令

use diagnostics;
use diagnostics -verbose;

enable  diagnostics;
disable diagnostics;

使用 splain 獨立過濾器程式

perl program 2>diag.out
splain [-v] [-p] diag.out

使用診斷從行為異常的指令碼取得堆疊追蹤

perl -Mdiagnostics=-traceonly my_script.pl

說明

diagnostics 指令

此模組擴充了 perl 編譯器和 perl 直譯器(從執行 perl 搭配 -w 開關或 use warnings 執行)通常發出的簡潔診斷,並補充 perldiag 中更具說明性和親切的描述。與其他指令一樣,它會影響程式的編譯階段,而不僅僅是執行階段。

若要在程式中作為指令使用,只需在程式開始(或接近開始)時呼叫

use diagnostics;

(請注意,這啟用 perl 的 -w 旗標。)然後,整個編譯都會受到增強的診斷影響。這些診斷仍會傳送到 STDERR

由於執行時間和編譯時間問題之間的交互作用,而且這可能不是一個好主意,因此您可能無法使用 no diagnostics 在編譯時將它們關閉。但是,您可以使用 disable() 和 enable() 方法在執行時控制它們的行為,分別將它們關閉和開啟。

-verbose 旗標會在任何其他診斷之前先列印 perldiag 簡介。$diagnostics::PRETTY 變數可以為分頁器產生更漂亮的跳脫序列。

perl 本身發出的警告(或更精確地說,與 perldiag 中描述相符的警告)只會顯示一次(沒有重複的描述)。使用者程式碼產生的警告(例如 warn())不受影響,允許顯示重複的使用者訊息。

此模組也會在 perl 發生錯誤時,將堆疊追蹤新增至錯誤訊息中。這對於找出導致錯誤的原因很有用。-traceonly(或僅 -t)旗標會關閉警告訊息的說明,只留下堆疊追蹤。因此,如果您的指令碼發生錯誤,請使用以下指令再次執行它

perl -Mdiagnostics=-traceonly my_bad_script

以在錯誤發生時查看呼叫堆疊。透過提供 -warntrace(或僅 -w)旗標,發出的任何警告也會附帶堆疊追蹤。

splain 程式

另一個程式 splain 實際上只不過是連結到(可執行)diagnostics.pm 模組,以及連結到 diagnostics.pod 文件。-v 旗標類似於 use diagnostics -verbose 指令。-p 旗標類似於 $diagnostics::PRETTY 變數。由於您使用 splain 進行後處理,因此沒有必要啟用或停用處理。

與 pragma 不同,splain 的輸出會導向 STDOUT

範例

以下檔案必定會在執行時間和編譯時間觸發一些錯誤

use diagnostics;
print NOWHERE "nothing\n";
print STDERR "\n\tThis message should be unadorned.\n";
warn "\tThis is a user warning";
print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: ";
my $a, $b = scalar <STDIN>;
print "\n";
print $x/$y;

如果您偏好先執行程式,然後再查看其問題,請執行以下操作

perl -w test.pl 2>test.out
./splain < test.out

請注意,這通常無法在可疑來源的 shell 中執行,因為理論上

(perl -w test.pl >/dev/tty) >& test.out
./splain < test.out

因為您剛剛將現有的 stdout 移到其他地方。

如果您不想修改原始碼,但仍希望有即時警告,請執行以下操作

exec 3>&1; perl -w test.pl 2>&1 1>&3 3>&- | splain 1>&2 3>&- 

很方便,對吧?

如果您想即時控制警告,請執行類似以下操作。請務必先執行 use,否則您將無法取得 enable() 或 disable() 方法。

    use diagnostics; # checks entire compilation phase 
	print "\ntime for 1st bogus diags: SQUAWKINGS\n";
	print BOGUS1 'nada';
	print "done with 1st bogus\n";

    disable diagnostics; # only turns off runtime warnings
	print "\ntime for 2nd bogus: (squelched)\n";
	print BOGUS2 'nada';
	print "done with 2nd bogus\n";

    enable diagnostics; # turns back on runtime warnings
	print "\ntime for 3rd bogus: SQUAWKINGS\n";
	print BOGUS3 'nada';
	print "done with 3rd bogus\n";

    disable diagnostics;
	print "\ntime for 4th bogus: (squelched)\n";
	print BOGUS4 'nada';
	print "done with 4th bogus\n";

內部

診斷訊息在執行時會從 perldiag.pod 檔案取得(如果可用)。否則,它們可能會在建立 splain 套件時嵌入檔案中。請參閱 Makefile 以取得詳細資訊。

如果發現現有的 $SIG{__WARN__} 處理常式,它將繼續受到尊重,但只有在 diagnostics::splainthis() 函式(模組的 $SIG{__WARN__} 攔截器)對您的警告執行後才會執行。

如果您非常好奇正在攔截哪些類型的內容,可以設定 $diagnostics::DEBUG 變數。

BEGIN { $diagnostics::DEBUG = 1 } 

錯誤

無法說「不診斷」很煩人,但可能並非無法克服。

-pretty 指令呼叫得太晚,無法影響事項。您必須改為執行此操作,而且必須在載入模組之前執行。

BEGIN { $diagnostics::PRETTY = 1 } 

我可以在需要時才延遲編譯,以加快啟動速度,但這會在 Perl 5.001e 中使用 pragma 形式時出現「恐慌:頂層」錯誤。

雖然這份文件有點不嚴肅,但如果您使用一個名為splain的程式,您應該會期待一點異想天開。

作者

Tom Christiansen <tchrist@mox.perl.com>,1995 年 6 月 25 日。