16

我时不时地在 StackOverflow 上看到人们推广autodie的使用。但是在这里和网络其他地方的代码中,我不经常看到自动死亡。有一些缺点吗?使用 autodie 时我会丢失一些东西吗?(在使用 autodie 时,我有被宠坏的想法)

4

4 回答 4

18

autodie文档列出了您应该注意的几个问题和错误。但是,其中大多数都是相对较小的,从长远来看也是可以修复的。

除此之外没有真正的缺点,除了在旧的 perl 版本上运行时可能会产生额外的依赖性。它不经常使用的事实很可能是由于它相对较新。尽管如此,autodie(甚至是旧Fatal模块)通常都是一个好主意。

于 2010-10-15T11:19:14.383 回答
10

这项技术大部分都很好,但它的作用是远距离和神奇的。一些只阅读部分代码的人可能不明白会发生什么,因为autodie远离他们检查的代码。由于不是每个人都使用它,而且它最近才成为一种做法,我怀疑大多数人都不会期待它。这并不是什么大不了的事,但那种事情对我来说总是很丑陋。

于 2010-10-15T17:49:13.070 回答
5

有一种语言模型遵循C 的基于函数的范例,其中所有函数都返回一个值,由用户检查返回值。Perl 在这个组中。如果我调用一个函数,我有责任检查该函数是否真的返回了有用的东西。

还有另一种语言模型遵循Java 的基于异常的范例,其中失败的函数返回异常,如果用户需要处理异常,他们必须显式处理异常。自 Java 以来编写的大多数现代语言都遵循这种基于异常的方法。

较新的语言是基于异常的,因为它处理了懒惰的开发人员问题。在C风格的编程语言中,如果开发人员忘记或懒得检查函数的退出状态,程序会继续。在Java风格的编程语言中,程序会死掉。在这两种情况下,开发人员都可以处理无效函数结果的问题,这是基于异常的语言迫使开发人员这样做。

怎么没看到use autodie这里?几种理论:

这是新的

pragma 是相当新的autodie,大多数开发人员没有很好的方法将新知识融入他们的 Perl 编程。例如,say自 5.10 以来一直存在,但我仍然看到很少有开发人员使用它,尽管它比print. 如果开发人员autodie在最初学习 Perl 时没有学习,他们可能永远不会知道它。

Perl 中没有 Try/Catch 语法

Perl 通常是这样工作的:

open $fh, "<", $file;
if ( not defined $fh ) {
   ...    # What I do if `$fh` didn't get set.
}

我检查了$fh我的open声明之后的值(好吧,通常你检查它本身的返回值open而不是打开的值$fh,但请耐心等待!)。语法相当简单和干净。这很容易理解。

如果您使用autodie并采用基于异常的方法会怎样?Perl中没有像 Java 中那样的内置try/catch语句。相反,您采用了一种半笨拙的使用方式eval

use autodie;
my $fh;     # Got to be declared outside of the eval
eval {
    open $fh, "<", $file;
};        # Don't forget that semicolon!
if ( $@ ) {
   ...    # What I do if function "foo" doesn't return a good value...
}

你能说恶心吗?我知道你可以!因为$fh是词法范围的,所以我必须在我的eval. 另外,我什至没有涉及成为$@全局范围变量的整个问题!

这是不完整的方式

大多数模块和内置函数都无法使用,autodie它们或多或少仅限于 IO 调用、forksystemexec,即使在这里,它也是不完整的:print并且flock不能使用autodie. 除此之外,没有其他 Perl 内置函数可用于autodie. 从空数组中弹出值不会迫使我的程序发牢骚。很少有模块会检查状态autodie以查看其函数或方法是否应该croak返回错误值。因此,将 Perl 转变为基于异常的语言的整个想法并没有发生。

即使你认为autodie可以工作的地方也没有。如果您用于File::Copy获取copyandmove命令,请不要依赖于autodie捕获错误的文件副本。您仍然需要检查copy. 如果你使用File::IO,所有的赌注autodie都将被取消。

因此,autodie它并没有完全兑现将 Perl 转变为更加基于异常的编程语言的大胆承诺。对于大多数人来说,它主要是 catchopen语句,大多数开发人员对open ... or die....

我喜欢基于异常的开发方法,并且我相信所有模块都应该默认出现错误。强制开发人员处理异常而不是忽略它们。当出现问题时,我编写我的模块和函数来发牢骚,并用于eval处理异常。不幸的是,autodie现在并没有做很多事情。

于 2014-08-19T16:52:12.030 回答
1

另一个考虑因素是 autodie 和 utf8::all 直到最近发布的 utf8::all才能很好地结合在一起。utf8::all 是另一个方便的模块,它和 autodie 一样,帮助设置 Perl 自动执行常见任务(这次是 unicode)。

于 2012-10-18T15:01:48.130 回答