評估和死亡
這是處理異常的內建方法,而不依賴於像 Try::Tiny 這樣的第三方庫。
my $ret;
eval {
$ret = some_function_that_might_die();
1;
} or do {
my $eval_error = $@ || "Zombie error!";
handle_error($eval_error);
};
# use $ret
我們濫用die
具有錯誤返回值的事實,並且整個程式碼塊的返回值是程式碼塊中最後一個表示式的值:
- 如果
$ret
被成功分配,那麼1;
表示式是eval
程式碼塊中發生的最後一件事。因此eval
程式碼塊具有真值,因此or do
塊不會執行。 - 如果
some_function_that_might_die()
做了die
,那麼在eval
程式碼塊中發生的最後一件事就是die
。因此,eval
程式碼塊具有錯誤值,並且or do
塊確實執行。 - 你必須在
or do
區塊做的第一件事是閱讀$@
。這個全域性變數將儲存傳遞給die
的任何引數。|| "Zombie Error"
後衛很受歡迎,但在一般情況下是不必要的。
這一點很重要,因為有些並非所有程式碼都通過呼叫 die 而失敗,但無論如何都可以使用相同的結構。考慮一個返回的資料庫函式:
- 成功影響的行數
'0 but true'
如果查詢成功但沒有行受到影響0
如果查詢不成功。
在這種情況下,你仍然可以使用相同的習語,但你必須跳過最後的 1;
,這個函式必須是 eval 中的最後一個。像這樣的東西:
eval {
my $value = My::Database::retrieve($my_thing); # dies on fail
$value->set_status("Completed");
$value->set_completed_timestamp(time());
$value->update(); # returns false value on fail
} or do { # handles both the die and the 0 return value
my $eval_error = $@ || "Zombie error!";
handle_error($eval_error);
};