Perl中的异常有什么坏处?
在
another question的讨论让我想知道:其他编程语言的异常系统有什么Perl的缺乏?
Perl内置的异常是有点特别的,因为他们像Perl 5对象系统一样,作为一个事后的想法,它们被重新绑定,并且它们重载了没有专门用于异常的其他关键字(eval和die)。 与具有内置try / throw / catch类型语法的语言相比,语法可能有点丑陋。我通常这样做: eval { do_something_that_might_barf(); }; if ( my $err = $@ ) { # handle $err here } 有几个CPAN模块提供语法糖添加try / catch关键字和允许容易声明异常类层次结构和whatnot。 我看到Perl的异常系统的主要问题是使用特殊的全局$ @持有当前的错误,而不是一个专门的捕获类型的机制,可能更安全,从范围的角度,虽然我从来没有亲自经历任何问题$ @得到munged。 解决方法
一些异常类,例如
Error,不能处理try / catch块内的流控制。这会导致微妙的错误:
use strict; use warnings; use Error qw(:try); foreach my $blah (@somelist) { try { somemethod($blah); } catch Error with { my $exception = shift; warn "error while processing $blah: " . $exception->stacktrace(); next; # bzzt,this will not do what you want it to!!! }; # do more stuff... } 解决方法是使用状态变量并检查try / catch块之外,这对我看起来可怕的像臭的n00b代码。 另外两个“陷阱”在错误(这两个都让我很伤心,因为他们是可怕的调试,如果你没有遇到这个) use strict; use warnings; try { # do something } catch Error with { # handle the exception } 看起来很明智,对吧?此代码编译,但导致奇怪和不可预测的错误。问题是: > use错误qw(:try)被省略,所以try {} …块将被错误解释(你可能会看到一个警告,这取决于你的代码的其余部分) 哦,是的,这也提醒我,因为try,catch等是方法调用,这意味着这些块内的调用堆栈不会是你期望的。 (实际上有两个额外的堆栈级别,因为Error.pm内部调用)因此,我有一些模块充满了样板代码,这只是增加了杂乱: my $errorString; try { $x->do_something(); if ($x->failure()) { $errorString = 'some diagnostic string'; return; # break out of try block } do_more_stuff(); } catch Error with { my $exception = shift; $errorString = $exception->text(); } finally { local $Carp::CarpLevel += 2; croak "Could not perform action blah on " . $x->name() . ": " . $errorString if $errorString; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |