[编辑] - 事后看来,这个问题被误导了。我没有删除它,因为它是错误使用eval 的一个很好的例子,并通过 Perl :: Critic 进行正确的批评。
Perl Critic对下面的代码提出了以下批评:
未经测试的eval的返回值。您不能依赖
$@/$EVAL_ERROR
的值来判断eval是否失败
my $Jet = Win32::OLE->CreateObject('DAO.DBEngine.36')
or croak "Can't create Jet database engine.";
my $DB = $Jet->OpenDatabase($DBFile)
# code omitted for the sake of brevity
# perl script writes results to Access db via an append query
$DB->Execute( $SQLquery, 128 ); #128=DBFailOnError
eval {$err = Win32::OLE->LastError()} ; #<<<< PROBLEM LINE SEE FEEDBACK BELOW
if ( $err){
print $ERROR "WIN32::OLE raised an exception: $err\n";
Win32::OLE->LastError(0); # this clears your error
}
我的想法是我使用eval
来检测错误对象的存在,并在Win32:OLE
模块上检测错误并报告错误。
我可以安全地忽视这些批评吗?
答案 0 :(得分:3)
暂不使用perl-critic
版本,您的代码没有多大意义。
Win32::OLE docs解释何时抛出异常(以及如何自动捕获它们)。
假设您的程序没有死亡, LastError
只会在发生错误后向您提供有关错误的信息。将其包含在eval
中是毫无意义的。
更新:我会写下以下内容(未经测试,因为我现在在Linux上,现在无法访问Windows):
use strict;
use warnings;
use Carp;
use Win32;
use Win32::OLE;
$Win32::OLE::Warn = 3;
# No need for this eval if you are OK with the default error message
my $Jet = eval {
Win32::OLE->CreateObject('DAO.DBEngine.36')
} or croak sprintf(
"Can't create Jet database engine: %s",
win32_error_message(Win32::OLE->LastError)
);
# No need for this eval if you are OK with the default error message
my $DB = eval {
$Jet->OpenDatabase($DBFile)
} or croak sprintf(
"Can't open database '$DBFile': %s",
win32_error_message(Win32::OLE->LastError)
);
my $result = eval {
$DB->Execute( $SQLquery, 128 )
};
unless (defined $result) {
print $ERROR win32_error_message(Win32::OLE->LastError);
Win32::OLE->LastError(0);
}
答案 1 :(得分:2)
documentation详细说明了该消息的含义。简而言之,它告诉您在$@
之后不单独依赖eval
,而是还要检查eval
的返回值。
但是,在您的情况下,问题是您没有检查eval
的返回值,也不检查$@
,而且您似乎使用了eval
完全是多余的,因为你调用的方法不应该抛出任何异常。