前言
在實際情境中運行的程式,即使程式本身沒有臭蟲 (bug),仍然要面對許多可能的錯誤 (error) 或例外 (exception)。例如,想要將某個字串轉成數字,但字串本身不是合法的數字;想要讀取某個外部檔案,卻權限不足;想要解析某個 XML 檔案,但該 XML 檔案內有錯誤的格式。我們不能天真地認定程式不會發生錯誤,而要詳細考慮可能發生的錯誤,撰寫相關的程式碼。
拋出例外事件
die
是 Perl 5 留下來的語法,後面接一個字串,可以拋出例外事件,見下例:
1 + 2 == 3 or die "Wrong logic";
有型別的例外事件
Perl 6 增加有型別的例外事件,主要是為了增加錯誤訊息的可讀性,如下例:
die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"))
想要使用內建的例外物件,可見官網有關 Exception 類別的說明,此處不逐一列出。
接收例外事件
使用 CATCH
區塊可以接住例外事件,可搭配 when
,對於不同類型的例外以不同方式處理,如下例:
die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"));
CATCH {
when X::IO { say "some kind of IO exception was caught!"; }
default { say "Something wrong"; }
}
進入 CATCH
區塊後,會跳出程式,不會再執行後續的程式碼,如下例:
die "Something happens";
CATCH {
default { .say; }
}
say "This won't happen";
加上 .resume
後,可從例外中回復,如下例:
die "Something happens";
CATCH {
default {
.say;
.resume;
}
}
say "This will happen as well";
try
try
區塊可將可能會發生例外的程式碼包住,引發錯誤後仍可繼續執行程式,如下例:
try {
die "Something happens";
CATCH {
default { .say; }
}
}
say "This will happen as well";
throw
throw
由 Exception 物件呼叫,作用類似於 die
。見下例:
X::AdHoc.new(:payload<foo>).throw;
"OHAI".say;
CATCH {
when X::AdHoc { .resume }
}
"OBAI".say;
自訂 Exception 類別
除了使用內建的 exceptions 外,使用者也可自訂自己的 Exception 類別,建立 Exception 類別時至少要建立一個回傳字串的 message
方法。以下例子摘自 Perl 6 官網:
class X::YourApp::SomeError is Exception {
method message() {
"A YourApp-Specific error occurred: out of coffee!";
}
}