在挖掘一些旧的源代码时,我看到了以下内容:
my $module = $some{module};
eval "require $module";
die "Bad module\n$@" if $@;
Run Code Online (Sandbox Code Playgroud)
当我理解代码的作用时,它会尝试"需要"一个模块并在它不成功时死掉 - perlcritic抱怨它
第31栏第13栏"eval"的表达形式.参见PBP第161页.(严重程度:5)
不幸的是我没有PBP书,所以想知道上面的正确方法是什么...
此外,在相同的来源发现:
sub test_repo_file {
my($self, $repo, $test) = @_;
my $abspath = repo_abs_path($repo);
return "eval -$test $abspath";
}
Run Code Online (Sandbox Code Playgroud)
这里不明白什么解决了"eval",并且perlcritic再次抱怨"字符串评估"......
有人可以解释关于"字符串评估"的基本要点以及如何正确编写上述内容吗?
跑步perlcritic --verbose '%d\n'也会给你解释:
每次执行时都会重新编译`eval'的字符串形式,而块形式只编译一次.此外,字符串形式不提供编译时警告.
Run Code Online (Sandbox Code Playgroud)eval "print $foo"; # not ok eval {print $foo}; # ok
它适用于第一种情况.
第二种情况不会为我生成任何消息.不是吗?
return eval "-$test $abspath"
Run Code Online (Sandbox Code Playgroud)
你不能在这里使用块eval.您应该验证$ test是否真的包含它应该包含的内容
$test =~ /^[a-z]$/i
Run Code Online (Sandbox Code Playgroud)
并避免评估$ abspath:
eval "-$test \$abspath"
Run Code Online (Sandbox Code Playgroud)
如果你对它没问题,你可以添加
## no critic
Run Code Online (Sandbox Code Playgroud)
到最后一行.
很少有用户应该使用eval EXPR. 大多数情况下,它在不应该使用时(例如s/.../eval($repl)/e)被用作模板系统,或者在eval BLOCK应该使用时用于捕获异常。
如果有理由使用它,就是执行生成的代码或用户提交的代码。生成代码既棘手又容易出错,而且错误具有安全隐患。执行用户提交的代码是一个主要的安全问题。因此,eval EXPR应仔细审查每次使用。
perlcritic鉴于几乎每次使用都是具有重大安全隐患的错误,因此标记其使用是非常合适的。
在您的情况下,使用eval EXPR是次优的。我会用
my $path = $module . ".pm";
$path =~ s{::}{/}g;
eval { require $path }
Run Code Online (Sandbox Code Playgroud)
是的,这是便携式的。