autodie有缺点吗?

时间:2010-10-15 11:08:20

标签: perl autodie

我一次又一次地看到StackOverflow上的人们推广使用autodie。但是在这里的代码和网络的其他地方,我并不经常看到autodie。有一些缺点吗?使用autodie时我会丢失什么吗? (我有想法在使用autodie时被宠坏了)

4 个答案:

答案 0 :(得分:18)

autodie documentation列出了一些你应该注意的问题和错误。但是,大多数都是相对较小的,从长远来看也是可以修复的。

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

答案 1 :(得分:8)

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

答案 2 :(得分:5)

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

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

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

为什么不在这里看到use autodie?几个理论:

这是新的

autodie编译指示是相当新的,并且大多数开发人员没有很好的方法将新知识合并到他们的Perl编程中。例如,say自5.10以来就已存在,但我仍然看到很少有开发人员使用它,尽管它比print有了很大的改进,而且使用起来很简单。如果开发人员在最初学习Perl时没有学习autodie,他们可能永远不会知道它。

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中没有内置的try/catch语句,就像在Java中一样。相反,你采用半笨拙的方式使用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一起使用,fork或多或少限于IO调用,systemexecprint,即使在这里,它不完整:flockautodie不适用于autodie。除此之外,没有其他Perl内置函数可以与autodie一起使用。从空数组中弹出值不会强制我的程序呱呱叫。很少有模块检查croak的状态,以查看其功能或方法是autodie而不是返回 false 值。因此,将Perl转换为基于异常的语言的整个想法都不会发生。

即使您认为File::Copy可行的地方也不行。如果您使用copy获取moveautodie命令,请不要依赖copy来捕获错误的文件副本。您仍需要检查File::IO的返回值。如果您使用autodie,则autodie的所有投注均已关闭。

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

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

答案 3 :(得分:1)

另一个考虑因素是autodie和utf8 :: all在recent release of utf8::all之前没有很好地协同工作。 utf8 :: all是另一个便利模块,像autodie一样,有助于设置Perl自动执行常见任务(这次是unicode)。