autodie - 使用词法范围替换函数,使其成功或失败
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
模块,则可以确保不会发生行为更改。
可以使用 autodie
为所有 Perl 的内置函数(包括 system
和 exec
)启用
use autodie qw(:all);
autodie 编译指令不检查对 print
的调用。
如果 flock
由于 EWOULDBLOCK
(或等效)条件而返回 false,则不认为是错误。这意味着当使用 LOCK_NB
选项调用 flock
时,仍然可以使用测试 flock
返回值的常见约定
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 导入到不同的命名空间。但是,您必须为此传递一个“调用者深度”(而不是包名称)才能正常工作。
当使用 autodie
或 Fatal
与包文件句柄(例如,FILE
)一起使用时,可能会生成“仅使用一次”警告。强烈建议改用标量文件句柄。
当对用户子例程使用 autodie
或 Fatal
时,这些子例程的声明必须出现在 Fatal
或 autodie
的首次使用之前,或已从模块中导出。尝试对其他用户子例程使用 Fatal
或 autodie
将导致编译时错误。
由于 Perl 中的一个错误,autodie
可能会“丢失”任何与自动死亡内置或函数同名的格式。
如果在名称看起来像字符串求值的文件中使用 autodie
,例如 eval (3),则 autodie
可能无法正常工作。
由于 autodie
的当前实现,在 eval 的字符串版本附近或与之一起使用时,可能会看到意外的结果。使用块求值时不存在这些错误。
仅在 Perl 5.8 下,autodie
不会传播到字符串 eval
语句中,尽管它可以在字符串 eval
中显式启用。
仅在 Perl 5.10 下,当 autodie
生效时使用字符串求值会导致 autodie 行为泄漏到周围范围。可以通过在范围末尾使用 no autodie
来显式删除 autodie 的效果,或避免使用字符串求值来解决此问题。
使用块求值时不存在这些错误。将 autodie
与块求值一起使用被认为是良好的做法。
请通过 https://github.com/pjf/autodie/issues 上的 GitHub Issue Tracker 报告错误。
如果您发现此模块有用,请考虑在 http://cpanratings.perl.org/rate?distribution=autodie 上的 CPAN 评级服务对其进行评级。
模块作者很想知道 autodie
如何让您的生活变得更好(或更糟)。反馈可以发送到 <[email protected]>。
版权所有 2008-2009,Paul Fenwick <[email protected]>
本模块是免费软件。您可以根据与 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 找到。