在挖掘一些旧的源代码时,我看到了以下内容:
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”的基本观点吗?以及如何正确地写上面的内容?
2条答案
按热度按时间46qrfjad1#
运行
perlcritic --verbose '%d\n'
也会给你给予解释:字符串形式的“eval”在每次执行时都会被重新编译,而块形式的“eval”只被编译一次。此外,字符串形式的“eval”不会给出给予编译时警告。
它适用于第一种情况。
第二个案例并没有给我产生任何信息。它不是更
这里不能使用block eval。应该验证$test是否真的包含了它应该包含的内容
并避免$abspath的求值:
如果你同意的话,你可以加上
到队伍的尽头。
hjqgdpho2#
很少有用户需要使用
eval EXPR
。大多数情况下,它被用作模板系统,而实际上并不需要(例如s/.../eval($repl)/e
),或者在应该使用eval BLOCK
的情况下用于捕获异常。如果有理由使用
eval EXPR
,那就是执行生成的代码或用户提交的代码。生成代码很棘手,容易出错,错误会带来安全隐患。执行用户提交的代码是一个主要的安全问题。因此,每次使用eval EXPR
都应该仔细检查。perlcritic
标记它的用法是非常合适的,因为实际上每一次使用都是一个具有重大安全影响的错误。在您的情况下,使用
eval EXPR
是次优的。(Yes,这是便携式的。)
更好的是,还有Module::Load。它甚至是一个核心模块。