2

[编辑] - 事后看来,这个问题被误导了。我没有删除它,因为它是Perl::Critic错误使用 eval和正确批评的一个很好的例子。

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模块上检测错误并报告它。

我可以安全地忽略批评吗?

4

2 回答 2

3

撇开问题不谈perl-critic,您的代码没有多大意义。

Win32::OLE 文档解释了何时抛出异常(以及如何自动捕获它们)。

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);
}
于 2009-10-16T13:05:22.867 回答
2

该消息的含义在文档中有详细说明。简而言之,它告诉你不要$@单独依赖一个eval,还要检查它的返回值eval

但是,在您的情况下,问题在于您既没有检查返回值,eval也没有检查$@,而且您的使用似乎eval是完全多余的,因为您调用的方法不应该抛出任何异常。

于 2009-10-16T09:47:59.503 回答