# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
eval {
die "Oops!";
};
if (my $e = $@) {
print("Something went wrong: $e\n");
}
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
use feature qw(switch);
eval {
use autodie;
open(my $fh, '<', $some_file);
my @records = <$fh>;
# Do things with @records...
close($fh);
};
given ($@) {
when (undef) { say "No error"; }
when ('open') { say "Error from open"; }
when (':io') { say "Non-open, IO error."; }
when (':all') { say "All other autodie errors." }
default { say "Not an autodie error at all." }
}
7条答案
按热度按时间rn0zuynd1#
您最好使用Try::Tiny,它将帮助您避免使用旧的
perl
的许多陷阱。jpfvwuh42#
上次我检查的时候,Error已经过时了。但是下面是没有这个模块的情况:
基本上,使用eval代替
try
,使用die代替throw
,并在$@
中查找异常。eval块末尾的true值是一个习惯用法的一部分,用于防止$@
在Perl 5.14之前被再次使用之前被无意中更改,有关详细信息,请参见P::C::P::ErrorHandling::RequireCheckingReturnValueOfEval。例如,此代码存在此缺陷。但请注意,许多Perl操作在失败时并不引发异常;它们只是返回一个错误代码。这个行为可以通过autodie改变。如果你使用
autodie
,那么执行try/catch的标准方法是这样的(直接从autodie perldoc中得到):要获取堆栈跟踪,请查看Carp。
kgsdhlau3#
如果您想要比Try::Tiny更强大的功能,您可能需要尝试查看CPAN中的TryCatch模块。
zy1mlcev4#
原生
try
/catch
/finally
。Perl now has native support for
try
/catch
/finally
。您可以像这样使用它。从Perl v5.36, It's currently experimental.开始o2g1uqev5#
不幸的是,TryCatch在Devel::Declare的新版本0.006020中被破坏了,而且似乎没有修复它的意图。Perl核心开发团队还抱怨TryCatch依赖于一些时髦的东西来使它工作。
取而代之的是一个名为Nice::Try的新实现,它是一个完美的替代品。
没有必要像Try::Tiny那样在最后一个大括号上使用分号。
您还可以执行异常变量赋值,如
它还可以使用类异常,如
它还支持
finally
,它的特性集使它非常独特。充分披露:当TryCatch被破坏时,我开发了这个模块。
biswetbf6#
IMHO
Syntax::Keyword::Try
在大多数情况下是比Try::Tiny
更好的选择。Try::Tiny
比eval或Syntax::Keyword::Try
慢一个数量级。这是否是个问题取决于您的应用程序。对于许多应用程序来说,这并不重要。此外,如果您是来自另一种语言的访问者,
Try::Tiny
有一些语法怪癖,这使得它不太像您习惯的try/catch。uurity8g7#
正如前面所说的,旧的Error模块已经过时了,但是它在很长一段时间后仍然为我工作。自从我上次检查它是否仍然工作以来已经有一段时间了。我尝试了一些“更好的”替代品,发现它们都没有,所以我仍然使用Error。
这里有一个代码示例,它非常简单,并打印出捕获的错误。这是我写的一个应用程序,它使用Storable将序列化的Perl对象存储和检索到一个MLDBM后端文件。
这将返回类似以下内容的消息:
如果你想要完整的堆栈跟踪,你可以在调试器下运行代码,或者你可以阅读perldoc上的stacktrace方法,以获得Error类本身。我从来没有发现有必要让不在调试器下运行的应用程序打印完整的堆栈跟踪,所以我的集合中没有任何这样的例子可以粘贴。
我希望这能帮上忙。有时候你只需要等待恐龙的出现。