内容

名称

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 将为 closefcntlopensysopen 启用 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)。请注意,systemexec 默认情况下未启用。system 需要安装可选的 IPC::System::Simple 模块,并且启用 systemexec 将使它们的奇异形式无效。有关更多详细信息,请参阅下面的 "BUGS"

语法

use autodie qw(:1.994);

允许使用特定版本的 :default 列表。这提供了使用默认方法的便利性,但如果升级 autodie 模块,则可以确保不会发生行为更改。

可以使用 autodie 为所有 Perl 的内置函数(包括 systemexec)启用

use autodie qw(:all);

特定于函数的注释

print

autodie 编译指令不检查对 print 的调用

flock

如果 flock 由于 EWOULDBLOCK(或等效)条件而返回 false,则不认为是错误。这意味着当使用 LOCK_NB 选项调用 flock 时,仍然可以使用测试 flock 返回值的常见约定

use autodie;

if ( flock($fh, LOCK_EX | LOCK_NB) ) {
    # We have a lock
}

如果 flock 返回 false 并带有任何其他错误,则自动死亡的 flock 将生成一个异常。

system/exec

在以下情况下,内置函数 system 被认为失败

成功时,自动死亡形式的 system 返回退出值,而不是 $? 的内容。

可以将其他允许的退出值作为可选的第一个参数提供给自动死亡的 system

system( [ 0, 1, 2 ], $cmd, @args);  # 0,1,2 are good exit values

autodie 使用 IPC::System::Simple 模块来更改 system。有关更多信息,请参阅其文档。

autodie 应用于 systemexec 会导致奇异形式 system { $cmd } @args exec { $cmd } @args 被视为语法错误,直到词法作用域结束。如果您确实需要使用奇异形式,则可以调用 CORE::systemCORE::exec,或在调用奇异形式之前使用 no autodie qw(system exec)

陷阱

如果函数在列表上下文中被调用,则假定它们在返回空列表或仅包含单个未定义元素的列表时失败。

某些内置函数(例如 chdirtruncate)具有无法完全用 Perl 原型表示的调用签名。这意味着某些有效的 Perl 代码在 autodie 下将无效。例如

chdir(BAREWORD);

如果没有 autodie(并且假定 BAREWORD 是一个打开的文件句柄/目录句柄),则这是对 chdir 的有效调用。但在 autodie 下,chdir 的行为就像它具有原型 ";$",因此 BAREWORD 将是一个语法错误(在 "use strict" 下。如果没有 strict,它将被解释为文件名)。

诊断

:void 不能与词法作用域一起使用

:void 选项在 Fatal 中受支持,但在 autodie 中不受支持。要解决此问题,可以使用 no autodie 显式禁用 autodie,直到当前块结束。要仅禁用单个函数(例如 open)的 autodie,请使用 no autodie qw(open)

autodie 不执行对调用上下文的检查以确定是否抛出异常;使用 autodie 显式处理错误是一个深思熟虑的功能。

未为 %s 定义用户提示

您坚持为用户子例程提供提示,方法是在子例程名称本身之前添加 !,或在 autodie 参数列表中靠前。但是,有问题的子例程没有任何可用的提示。

另请参见 Fatal 中的“诊断”

提示和技巧

将 autodie 导入到“caller”之外的另一个命名空间

可以通过使用 Import::Into 将 autodie 导入到不同的命名空间。但是,您必须为此传递一个“调用者深度”(而不是包名称)才能正常工作。

BUG

当使用 autodieFatal 与包文件句柄(例如,FILE)一起使用时,可能会生成“仅使用一次”警告。强烈建议改用标量文件句柄。

当对用户子例程使用 autodieFatal 时,这些子例程的声明必须出现在 Fatalautodie 的首次使用之前,或已从模块中导出。尝试对其他用户子例程使用 Fatalautodie 将导致编译时错误。

由于 Perl 中的一个错误,autodie 可能会“丢失”任何与自动死亡内置或函数同名的格式。

如果在名称看起来像字符串求值的文件中使用 autodie,例如 eval (3),则 autodie 可能无法正常工作。

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 相同的条款分发它。

另请参阅

Fatalautodie::exceptionautodie::hintsIPC::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 找到。