Carp - 模組的替代警告和 die
use Carp;
# warn user (from perspective of caller)
carp "string trimmed to 80 chars";
# die of errors (from perspective of caller)
croak "We're outta here!";
# die of errors with stack backtrace
confess "not implemented";
# cluck, longmess and shortmess not exported by default
use Carp qw(cluck longmess shortmess);
cluck "This is how we got here!"; # warn with stack backtrace
my $long_message = longmess( "message from cluck() or confess()" );
my $short_message = shortmess( "message from carp() or croak()" );
Carp 常式在您自己的模組中很有用,因為它們的作用就像 die()
或 warn()
,但訊息更有可能對模組使用者有幫助。對於 cluck()
和 confess()
,該內容是呼叫堆疊中每個呼叫的摘要;longmess()
傳回錯誤訊息的內容。
對於較短的訊息,您可以使用 carp()
或 croak()
,它們會報告錯誤來自您的模組被呼叫的地方。shortmess()
傳回此錯誤訊息的內容。沒有保證那是錯誤所在,但這是一個良好的推測。
Carp
會注意不要在組裝錯誤訊息時覆蓋狀態變數 $!
和 $^E
。這表示 $SIG{__DIE__}
或 $SIG{__WARN__}
處理常式可以在這些變數中擷取錯誤資訊(如果需要擴充錯誤訊息,且呼叫 Carp
的程式碼在那裡留下有用的值)。當然,Carp
無法保證後者。
您也可以透過變更 Carp
名稱空間中的一些全域變數,來變更 Carp
的輸出和邏輯運作方式。請參閱下方有關 "全域變數" 的章節。
以下是 carp
和 croak
運作方式的更完整說明。它們會在呼叫堆疊中搜尋一個函式呼叫堆疊,在其中它們未被告知不應有錯誤。如果每個呼叫都被標記為安全,它們會放棄並提供完整的堆疊回溯。換句話說,它們假設第一個看似潛在的可疑對象就是罪魁禍首。它們判斷呼叫是否不應產生錯誤的規則如下:
從套件到自身的任何呼叫都是安全的。
套件宣稱不會有錯誤呼叫到或從套件,這些套件已明確標記為安全,方法是包含在 @CARP_NOT
中,或(如果該陣列為空)@ISA
。覆寫 @ISA 所說內容的能力在 5.8 中是新的。
對項目 2 的信任是遞移的。如果 A 信任 B,而 B 信任 C,則 A 信任 C。因此,如果您沒有使用 @CARP_NOT
覆寫 @ISA
,則這種信任關係等同於「繼承自」。
從 Perl 內部模組的任何呼叫都是安全的。(沒有任何東西可以阻止使用者模組將自己標記為 Perl 的內部模組,但這種做法並不鼓勵。)
對 Perl 警告系統(例如 Carp 本身)的任何呼叫都是安全的。(此規則會阻止它在您呼叫 carp
或 croak
時報告錯誤。)
$Carp::CarpLevel
可以設定為跳過固定數量的其他呼叫層級。不建議使用此功能,因為很難讓它正確運作。
作為除錯輔助工具,您可以強制 Carp 將 croak 視為 confess,將 carp 視為 cluck,並跨越所有模組。換句話說,強制提供詳細的堆疊追蹤。當您嘗試了解為什麼會產生警告或錯誤,或從何處產生警告或錯誤時,這可能會非常有幫助。
此功能是透過「匯入」不存在的符號「verbose」來啟用的。您通常會透過說以下內容來啟用它
perl -MCarp=verbose script.pl
或在 PERL5OPT 環境變數中包含字串 -MCarp=verbose
。
或者,您可以將全域變數 $Carp::Verbose
設定為 true。請參閱下方 "全域變數" 章節。
在每個堆疊層級中,子常式的名稱會與其參數一起顯示。對於簡單的純量,這樣就足夠了。對於複雜的資料類型,例如物件和其他參考,這只會簡單地顯示 'HASH(0x1ab36d8)'
。
Carp 提供兩種方法來控制此問題。
對於物件,如果存在方法 CARP_TRACE
,則會呼叫該方法。如果此方法不存在,或者它遞迴進入 Carp
,或者它會擲出例外,則會略過此方法,而 Carp 會繼續執行下一個選項,否則會停止檢查並使用傳回的字串。建議將物件的類型納入字串中,以簡化除錯。
對於任何類型的參考,會檢查 $Carp::RefArgFormatter
(請參閱下方)。預期此變數為程式碼參考,並傳入目前的參數。如果此函式不存在(變數未定義),或者它遞迴進入 Carp
,或者它會擲出例外,則會略過此函式,而 Carp 會繼續執行下一個選項,否則會停止檢查並使用傳回的字串。
否則,如果 CARP_TRACE
和 $Carp::RefArgFormatter
都不可用,則會將值字串化,並忽略任何重載。
此變數會決定在輸出中要顯示字串評估的字元數。使用值 0
來顯示所有文字。
預設為 0
。
此變數會決定要列印函式每個引數的字元數。使用值 0
來顯示引數的完整長度。
預設為 64
。
此變數會決定要顯示每個函式的引數數。使用 false 值來顯示函式呼叫的所有引數。若要抑制所有引數,請使用 -1
或 '0 but true'
。
預設為 8
。
此變數會讓 carp()
和 croak()
產生堆疊回溯,就像 cluck()
和 confess()
一樣。這是 use Carp 'verbose'
在內部實作的方式。
預設為 0
。
此變數設定一個一般參數格式化器來顯示參照。實作 CARP_TRACE
的純量和物件不會經過此格式化器。不支援在此函式內呼叫 Carp
。
local $Carp::RefArgFormatter = sub {
require Data::Dumper;
Data::Dumper->Dump($_[0]); # not necessarily safe
};
此變數(在您的套件中)表示哪些套件不會被視為錯誤位置。carp()
和 cluck()
函式在報告錯誤發生位置時會略過呼叫者。
注意:此變數必須在套件的符號表中,因此
# These work
our @CARP_NOT; # file scope
use vars qw(@CARP_NOT); # package scope
@My::Package::CARP_NOT = ... ; # explicit package variable
# These don't work
sub xyz { ... @CARP_NOT = ... } # w/o declarations above
my @CARP_NOT; # even at top-level
使用範例
package My::Carping::Package;
use Carp;
our @CARP_NOT;
sub bar { .... or _error('Wrong input') }
sub _error {
# temporary control of where'ness, __PACKAGE__ is implicit
local @CARP_NOT = qw(My::Friendly::Caller);
carp(@_)
}
這會讓 Carp
將錯誤報告為來自不在 My::Carping::Package
或 My::Friendly::Caller
中的呼叫者。
另請閱讀上述 "DESCRIPTION" 區段,了解 Carp
如何決定從何處報告錯誤。
使用 @CARP_NOT
,而不是 $Carp::CarpLevel
。
覆寫 Carp
使用 @ISA
的方式。
這表示哪些套件是 Perl 的內部套件。Carp
絕不會將錯誤報告為來自 Perl 內部套件中的一行。例如
$Carp::Internal{ (__PACKAGE__) }++;
# time passes...
sub foo { ... or confess("whatever") };
會從 __PACKAGE__ 外部的第一個呼叫者開始提供完整的堆疊回溯。(除非該套件也是 Perl 的內部套件。)
這表示哪些套件是 Perl 警告系統的內部套件。對於產生完整的堆疊回溯,這與 Perl 的內部套件相同,堆疊回溯不會從列在 %Carp::CarpInternal
中的套件內部開始。但對於 carp
或 croak
產生的摘要訊息則略有不同。錯誤不會報告在任何呼叫 %Carp::CarpInternal
中套件的行上。
例如 Carp
本身列在 %Carp::CarpInternal
中。因此 confess
的完整堆疊回溯不會從 Carp
內部開始,而呼叫 croak
的簡短訊息也不會放在呼叫 croak
的行上。
此變數決定了在報告錯誤發生在呼叫 Carp
的函數之一時,要略過多少額外的呼叫框架,否則不會略過。在產生完整堆疊回溯的呼叫中,計算這些呼叫框架相當容易。然而,對於產生簡短訊息的呼叫,執行此會計要困難得多。通常,人們會略過太多呼叫框架。如果他們幸運的話,他們會略過足夠的呼叫框架,讓 Carp
徹底執行呼叫堆疊,意識到出了問題,然後產生完整的堆疊回溯。如果他們不幸,則錯誤會從呼叫堆疊中非常高的某個地方報告出來,這會造成誤導。
因此,最好避免使用 $Carp::CarpLevel
。改用 @CARP_NOT
、%Carp::Internal
和 %Carp::CarpInternal
。
預設為 0
。
Carp 常式目前無法處理例外物件。如果呼叫時第一個引數是參考,則它們會適當地呼叫 die() 或 warn()。
Carp 由 perl 5 協力廠商維護,作為核心 perl 5 版本控制儲存庫的一部分。請參閱 perlhack perldoc,了解如何提交修補程式並貢獻其中。
Carp 模組首次出現在 Larry Wall 的 perl 5.000 發行版中。從那時起,它已被多位 perl 5 協力廠商修改。Andrew Main (Zefram) <zefram@fysh.org> 將 Carp 分離成一個獨立的發行版。
版權所有 (C) 1994-2013 Larry Wall
版權所有 (C) 2011、2012、2013 Andrew Main (Zefram) <zefram@fysh.org>
此模組是免費軟體;您可以在與 Perl 相同的條款下重新分發或修改它。