perlcrist:eval“require $module”;

06odsfpq  于 2023-10-24  发布在  Perl
关注(0)|答案(2)|浏览(142)

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

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

虽然我理解代码的作用,但它会尝试“require”一个模块,当它不成功时就会死亡-perlcritic对此抱怨不已
第331行第13列“eval”的表达形式。见PBP第161页。(严重性:5)
不幸的是,我没有PBP的书,所以想知道什么是正确的方法,上述.
此外,在同一来源发现:

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

这里不明白什么解决了“eval”,perlcritic再次抱怨“字符串eval”.
有人能解释一下关于“字符串eval”的基本观点吗?以及如何正确地写上面的内容?

46qrfjad

46qrfjad1#

运行perlcritic --verbose '%d\n'也会给你给予解释:
字符串形式的“eval”在每次执行时都会被重新编译,而块形式的“eval”只被编译一次。此外,字符串形式的“eval”不会给出给予编译时警告。

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

它适用于第一种情况。
第二个案例并没有给我产生任何信息。它不是更

return eval "-$test $abspath"

这里不能使用block eval。应该验证$test是否真的包含了它应该包含的内容

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

并避免$abspath的求值:

eval "-$test \$abspath"

如果你同意的话,你可以加上

## no critic

到队伍的尽头。

hjqgdpho

hjqgdpho2#

很少有用户需要使用eval EXPR。大多数情况下,它被用作模板系统,而实际上并不需要(例如s/.../eval($repl)/e),或者在应该使用eval BLOCK的情况下用于捕获异常。
如果有理由使用eval EXPR,那就是执行生成的代码或用户提交的代码。生成代码很棘手,容易出错,错误会带来安全隐患。执行用户提交的代码是一个主要的安全问题。因此,每次使用eval EXPR都应该仔细检查。
perlcritic标记它的用法是非常合适的,因为实际上每一次使用都是一个具有重大安全影响的错误。
在您的情况下,使用eval EXPR是次优的。

my $path = ( $module =~ s{::}{/}gr ) . ".pm";
require $path;

(Yes,这是便携式的。)
更好的是,还有Module::Load。它甚至是一个核心模块。

相关问题