perlcritic:eval“require $ module”;

时间:2015-04-15 22:15:39

标签: perl perl-critic

在挖掘一些旧的源代码时,我看到了以下内容:

my $module = $some{module};
eval "require $module";
die "Bad module\n$@" if $@;

当我理解代码的作用时,它会尝试“需要”一个模块并在它失败时死掉 - perlcritic抱怨它

  

第31栏第13栏“eval”的表达形式。见第161页   PBP。 (严重程度:5)

不幸的是我没有PBP书,所以想知道上面的正确方法是什么......

另外,在相同的来源中发现:

sub test_repo_file {
    my($self, $repo, $test) = @_;
    my $abspath = repo_abs_path($repo);
    return "eval -$test $abspath";
}

这里不明白什么解决了“eval”,并且perlcritic再次抱怨“字符串评估”......

有人可以解释一下“字符串评估”的基本要点以及如何正确编写以上内容吗?

2 个答案:

答案 0 :(得分:7)

运行perlcritic --verbose '%d\n'也会给你解释:

  

`eval'的字符串形式每次执行时都会重新编译,       而块形式只编译一次。另外,字符串形式       没有给出编译时警告。

   eval "print $foo";        # not ok
   eval {print $foo};        # ok

它适用于第一种情况。

第二种情况不会为我生成任何消息。不是吗

return eval "-$test $abspath"

您无法在此处使用块评估。您应该验证$ test是否真的包含它应该

的内容
$test =~ /^[a-z]$/i

并避免评估$ abspath:

eval "-$test \$abspath"

如果你对此感到满意,你可以添加

## no critic

到行尾。

答案 1 :(得分:3)

很少有用户必须使用eval EXPR。大多数情况下,它不应该用作模板系统(例如s/.../eval($repl)/e),或者用于在应该使用eval BLOCK时捕获异常。

如果有理由使用它,则执行生成的代码或用户提交的代码。生成代码很棘手且容易出错,并且错误会产生安全隐患。执行用户提交的代码是一个主要的安全问题。因此,应仔细审核eval EXPR的每次使用。

perlcritic标记其用法是非常合适的,因为几乎每次使用都是一个具有重大安全隐患的错误。


在您的情况下,eval EXPR的使用不是最理想的。我用

my $path = $module . ".pm";
$path =~ s{::}{/}g;
eval { require $path }

是的,这是便携式的。