autodie - 使用具有詞法範圍的成功或 die 函式取代函式
use autodie; # Recommended: implies 'use autodie qw(:default)'
use autodie qw(:all); # Recommended more: defaults and system/exec.
use autodie qw(open close); # open/close succeed or die
open(my $fh, "<", $filename); # No need to check!
{
no autodie qw(open); # open failures won't die
open(my $fh, "<", $filename); # Could fail silently!
no autodie; # disable all autodies
}
print "Hello World" or die $!; # autodie DOESN'T check print!
bIlujDI' yIchegh()Qo'; yIHegh()!
It is better to die() than to return() in failure.
-- Klingon programming proverb.
autodie
pragma 提供一種便利的方式,可以用在失敗時擲回例外的等效函式取代通常在失敗時傳回 false 的函式。
autodie
pragma 具有詞法範圍,表示使用 autodie
變更函式和子常式只會變更其行為,直到封閉區塊、檔案或 eval
結束。
如果將 system
指定為 autodie
的引數,則它會使用 IPC::System::Simple 來執行繁重的工作。有關更多資訊,請參閱該模組的說明。
autodie
pragma 產生的例外是 autodie::exception 類別的成員。在 Perl 5.10 中處理這些例外的建議方式如下
eval {
use autodie;
open(my $fh, '<', $some_file);
my @records = <$fh>;
# Do things with @records...
close($fh);
};
if ($@ and $@->isa('autodie::exception')) {
if ($@->matches('open')) { print "Error from open\n"; }
if ($@->matches(':io' )) { print "Non-open, IO error."; }
} elsif ($@) {
# A non-autodie exception.
}
請參閱 autodie::exception 以取得更多有關查詢例外的資訊。
Autodie 使用一組簡單的類別將類似的內建函式分組在一起。要求類別類型(從冒號開始)將會為該類別下的所有內建函式啟用 autodie。例如,要求 :file
會為 close
、fcntl
、open
和 sysopen
啟用 autodie。
類別目前為
:all
:default
:io
read
seek
sysread
sysseek
syswrite
:dbm
dbmclose
dbmopen
:file
binmode
close
chmod
chown
fcntl
flock
ioctl
open
sysopen
truncate
:filesys
chdir
closedir
opendir
link
mkdir
readlink
rename
rmdir
symlink
unlink
:ipc
kill
pipe
:msg
msgctl
msgget
msgrcv
msgsnd
:semaphore
semctl
semget
semop
:shm
shmctl
shmget
shmread
:socket
accept
bind
connect
getsockopt
listen
recv
send
setsockopt
shutdown
socketpair
:threads
fork
:system
system
exec
請注意,雖然上述類別系統目前是嚴格的階層,但這不應被視為理所當然。
單純的 use autodie
表示 use autodie qw(:default)
。請注意,system
和 exec
預設不會啟用。system
需要安裝選用的 IPC::System::Simple 模組,而啟用 system
或 exec
會使它們的特殊形式失效。請參閱下方的 "BUGS" 以取得更多詳細資料。
語法
use autodie qw(:1.994);
允許使用特定版本的 :default
清單。這提供了使用預設方法的便利性,但如果升級 autodie
模組,則可以確保不會發生行為變更。
可以使用下列方式為 Perl 的所有內建函式(包括 system
和 exec
)啟用 autodie
use autodie qw(:all);
autodie pragma 不會檢查對 print
的呼叫。
如果 flock
因 EWOULDBLOCK
(或等效)條件而失敗,則不會被視為錯誤。這表示您仍然可以使用測試 flock
回傳值的一般慣例,並搭配 LOCK_NB
選項呼叫
use autodie;
if ( flock($fh, LOCK_EX | LOCK_NB) ) {
# We have a lock
}
如果 flock
因任何其他錯誤而回傳 false,自動終止 flock
會產生例外狀況。
在以下情況下,會視為 system
內建函式已失敗
命令未啟動。
命令被訊號終止。
命令回傳非零結束值(但請參閱下方)。
如果成功,自動終止形式的 system
會回傳結束值,而非 $?
的內容。
可以將其他允許的結束值提供為自動終止 system
的選用第一個參數
system( [ 0, 1, 2 ], $cmd, @args); # 0,1,2 are good exit values
autodie
使用 IPC::System::Simple 模組來變更 system
。請參閱其文件以取得更多資訊。
將 autodie
套用至 system
或 exec
會導致特殊形式 system { $cmd } @args
或 exec { $cmd } @args
被視為語法錯誤,直到詞法範圍結束為止。如果您真的需要使用特殊形式,您可以呼叫 CORE::system
或 CORE::exec
,或在呼叫特殊形式之前使用 no autodie qw(system exec)
。
如果函式在清單內容中呼叫,則假設如果函式回傳空清單,或僅包含單一未定義元素的清單,則函式已失敗。
有些內建函式(例如 chdir
或 truncate
)的呼叫簽章無法完全用 Perl 原型表示。這表示一些有效的 Perl 程式碼在 autodie 下會無效。例如
chdir(BAREWORD);
在沒有 autodie 的情況下(並假設 BAREWORD 是開啟的檔案處理常式/目錄處理常式),這是對 chdir 的有效呼叫。但在 autodie 下,chdir
的行為會像具有原型 ";$" 一樣,因此 BAREWORD 會是語法錯誤(在 "use strict" 下。在沒有 strict 的情況下,它會被解釋為檔案名稱)。
:void
選項在 Fatal 中受支援,但在 autodie
中不受支援。若要解決此問題,可以使用 no autodie
明確停用 autodie
,直到目前區塊結束為止。若要僅停用單一函式(例如 open)的 autodie,請使用 no autodie qw(open)
。
autodie
不會檢查呼叫內容以確定是否要擲回例外狀況;使用 autodie
進行錯誤處理的明確性是一項蓄意的功能。
您已堅持使用使用者子常式的提示,方法是將 !
加在子常式名稱本身之前,或在 autodie
參數清單中較前面。然而,有問題的子常式沒有任何可用的提示。
另請參閱 「Fatal 中的「診斷」。
可以使用 Import::Into 將 autodie 匯入不同的命名空間。不過,您必須傳遞「呼叫者深度」(而非套件名稱),才能正確執行此操作。
當使用套件檔案句柄(例如 FILE
)搭配 autodie
或 Fatal
時,可能會產生「僅使用一次」的警告。強烈建議改用純量檔案句柄。
當搭配使用者子常式使用 autodie
或 Fatal
時,這些子常式的宣告必須出現在第一次使用 Fatal
或 autodie
之前,或已從模組匯出。嘗試對其他使用者子常式使用 Fatal
或 autodie
會導致編譯時期錯誤。
由於 Perl 中的錯誤,autodie
可能會「遺失」與自動執行內建函式或函式同名的任何格式。
如果在看起來像是字串 eval 的檔案名稱(例如 eval (3))內使用 autodie
,autodie
可能無法正常運作。
由於目前 autodie
的實作方式,在 eval 的字串版本附近或搭配使用時,可能會看到意外的結果。使用區塊 eval 時,不會出現任何這些錯誤。
僅在 Perl 5.8 中,autodie
不會傳播到 eval 的字串陳述式,儘管它可以在 eval 的字串內明確啟用。
僅在 Perl 5.10 中,當 autodie
生效時使用 eval 的字串可能會導致 autodie 行為外洩到周圍的範圍。這可以用在範圍結尾加上 no autodie
來明確移除 autodie 的效果,或避免使用 eval 的字串來解決。
使用區塊 eval 時,不會出現任何這些錯誤。將 autodie
搭配區塊 eval 使用,被視為良好的做法。
請透過 https://github.com/pjf/autodie/issues 上的 GitHub Issue Tracker 回報錯誤。
如果您覺得此模組有用,請考慮在 http://cpanratings.perl.org/rate?distribution=autodie 上的 CPAN 評分服務評分。
模組作者很樂意聽聽 autodie
如何讓您的生活更好(或更糟)。回饋可以寄送至 <pjf@perltraining.com.au>。
版權所有 2008-2009,Paul Fenwick <pjf@perltraining.com.au>
此模組為免費軟體。您可以按照 Perl 本身的條款散布它。
Fatal、autodie::exception、autodie::hints、IPC::System::Simple
Perl 技巧,autodie,請參閱 http://perltraining.com.au/tips/2008-08-20.html
Mark Reed 和 Roland Giersig -- 克林貢語翻譯者。
請參閱 AUTHORS 檔案以取得完整名單。此檔案的最新版本可以在 https://github.com/pjf/autodie/tree/master/AUTHORS 找到。