die
引發例外。在 eval
內,例外會塞入 $@
,而 eval
會以未定義的值終止。如果例外在所有封裝的 eval
外,未捕捉的例外會印到 STDERR
,而 perl 會以表示失敗的結束代碼結束。如果您需要以特定結束代碼結束程序,請參閱 exit
。
等效範例
die "Can't cd to spool: $!\n" unless chdir '/usr/spool/news';
chdir '/usr/spool/news' or die "Can't cd to spool: $!\n"
大多數時候,die
會呼叫字串以用作例外。您可以提供一個單一非參考運算元作為例外,或提供兩個或更多項目的清單,這些項目會被字串化並串接以產生例外。
如果字串例外沒有以換行符號結尾,目前指令碼行號和輸入行號(如果有)以及換行符號會附加到其中。請注意,「輸入行號」(也稱為「區塊」)受限於目前生效的「行」概念,並且也可以用作特殊變數 $.
。請參閱 "$/" in perlvar 和 "$." in perlvar。
提示:有時在訊息中附加 ", stopped"
會讓訊息在附加字串 "at foo line 123"
時更有意義。假設您正在執行腳本 "canasta"。
die "/etc/games is no good";
die "/etc/games is no good, stopped";
分別產生
/etc/games is no good at canasta line 123.
/etc/games is no good, stopped at canasta line 123.
如果 LIST 為空或產生空字串,且 $@
已包含例外值(通常來自先前的 eval
),則在附加 "\t...propagated"
後會重複使用該值。這對於傳播例外很有用
eval { ... };
die unless $@ =~ /Expected exception/;
如果 LIST 為空或產生空字串,且 $@
包含具有 PROPAGATE
方法的物件參考,則會呼叫該方法,並提供額外的檔案和行號參數。回傳值會取代 $@
中的值;也就是說,就像呼叫 $@ = eval { $@->PROPAGATE(__FILE__, __LINE__) };
一樣。
如果 LIST 為空或產生空字串,且 $@
也為空,則會使用字串 "Died"
。
您也可以使用參考引數呼叫 die
,如果這在 eval
中被攔截,則 $@
會包含該參考。這允許使用維護例外任意狀態的物件來進行更精細的例外處理。這樣的方案有時比使用正規表示式比對 $@
的特定字串值更可取。
由於 Perl 會在顯示之前將未捕捉的例外訊息字串化,因此您可能需要對例外物件的字串化操作進行重載。有關這方面的詳細資訊,請參閱 重載。字串化的訊息不應為空,且應以換行符號結尾,以符合字串例外的處理方式。此外,由於無法在不破壞例外物件的情況下將其字串化,因此 Perl 不會嘗試將位置或其他資訊附加到參考例外。如果您想要複雜例外物件的位置資訊,您必須自行安排將位置資訊放入物件中。
由於 $@
是全域變數,因此請小心,分析由 eval
捕捉的例外不會取代全域變數中的參考。在進行任何操作之前,最簡單的方法是建立參考的本地副本。以下是一個範例
use Scalar::Util "blessed";
eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) };
if (my $ev_err = $@) {
if (blessed($ev_err)
&& $ev_err->isa("Some::Module::Exception")) {
# handle Some::Module::Exception
}
else {
# handle all other possible exceptions
}
}
如果未捕捉的例外導致直譯器退出,則退出碼會根據 $!
和 $?
的值,使用下列偽程式碼決定
exit $! if $!; # errno
exit $? >> 8 if $? >> 8; # child exit status
exit 255; # last resort
與 exit
一樣,$?
會在解除呼叫堆疊之前設定;任何 DESTROY
或 END
處理常式都可以變更此值,進而變更 Perl 的退出碼。
目的是將有關可能原因的盡可能多的資訊壓縮到系統結束代碼的有限空間中。但是,由於 $!
是 C 的 errno
的值,任何系統呼叫都可以設定這個值,這表示 die
使用的結束代碼值可能無法預測,因此不應依賴它,除了它是非零值。
你可以安排在 die
執行其動作之前執行回呼,方法是設定 $SIG{__DIE__}
鉤子。關聯的處理常式會以例外狀況作為引數呼叫,並且如果它認為合適,可以透過再次呼叫 die
來變更例外狀況。請參閱 "perlvar 中的 %SIG" 以取得有關設定 %SIG
項目的詳細資料,以及 eval
以取得一些範例。雖然此功能只在你的程式要結束之前執行,但目前並非如此:$SIG{__DIE__}
鉤子目前甚至在 eval
的區塊/字串中也會呼叫!如果某人在這種情況下希望鉤子什麼都不做,請將
die @_ if $^S;
作為處理常式的第一行(請參閱 "perlvar 中的 $^S")。由於這會促進距離上的奇怪動作,因此這種反直覺的行為可能會在未來的版本中修正。