我一次又一次地看到StackOverflow上的人们推广使用autodie。但是在这里的代码和网络的其他地方,我并不经常看到autodie。有一些缺点吗?使用autodie时我会丢失什么吗? (我有想法在使用autodie时被宠坏了)
答案 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的工作原理:
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调用,system
,exec
和print
,即使在这里,它不完整:flock
和autodie
不适用于autodie
。除此之外,没有其他Perl内置函数可以与autodie
一起使用。从空数组中弹出值不会强制我的程序呱呱叫。很少有模块检查croak
的状态,以查看其功能或方法是autodie
而不是返回 false 值。因此,将Perl转换为基于异常的语言的整个想法都不会发生。
即使您认为File::Copy
可行的地方也不行。如果您使用copy
获取move
和autodie
命令,请不要依赖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)。