我时不时地在 StackOverflow 上看到人们推广autodie的使用。但是在这里和网络其他地方的代码中,我不经常看到自动死亡。有一些缺点吗?使用 autodie 时我会丢失一些东西吗?(在使用 autodie 时,我有被宠坏的想法)
4 回答
该autodie
文档列出了您应该注意的几个问题和错误。但是,其中大多数都是相对较小的,从长远来看也是可以修复的。
除此之外没有真正的缺点,除了在旧的 perl 版本上运行时可能会产生额外的依赖性。它不经常使用的事实很可能是由于它相对较新。尽管如此,autodie
(甚至是旧Fatal
模块)通常都是一个好主意。
这项技术大部分都很好,但它的作用是远距离和神奇的。一些只阅读部分代码的人可能不明白会发生什么,因为autodie远离他们检查的代码。由于不是每个人都使用它,而且它最近才成为一种做法,我怀疑大多数人都不会期待它。这并不是什么大不了的事,但那种事情对我来说总是很丑陋。
有一种语言模型遵循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 调用、fork
、system
和exec
,即使在这里,它也是不完整的:print
并且flock
不能使用autodie
. 除此之外,没有其他 Perl 内置函数可用于autodie
. 从空数组中弹出值不会迫使我的程序发牢骚。很少有模块会检查状态autodie
以查看其函数或方法是否应该croak
返回错误值。因此,将 Perl 转变为基于异常的语言的整个想法并没有发生。
即使你认为autodie
可以工作的地方也没有。如果您用于File::Copy
获取copy
andmove
命令,请不要依赖于autodie
捕获错误的文件副本。您仍然需要检查copy
. 如果你使用File::IO
,所有的赌注autodie
都将被取消。
因此,autodie
它并没有完全兑现将 Perl 转变为更加基于异常的编程语言的大胆承诺。对于大多数人来说,它主要是 catchopen
语句,大多数开发人员对open ... or die...
.
我喜欢基于异常的开发方法,并且我相信所有模块都应该默认出现错误。强制开发人员处理异常而不是忽略它们。当出现问题时,我编写我的模块和函数来发牢骚,并用于eval
处理异常。不幸的是,autodie
现在并没有做很多事情。
另一个考虑因素是 autodie 和 utf8::all 直到最近发布的 utf8::all才能很好地结合在一起。utf8::all 是另一个方便的模块,它和 autodie 一样,帮助设置 Perl 自动执行常见任务(这次是 unicode)。