在挖掘一些旧的源代码时,我看到了以下内容:
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再次抱怨“字符串评估”......
有人可以解释一下“字符串评估”的基本要点以及如何正确编写以上内容吗?
答案 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 }
是的,这是便携式的。