使用eval插入变量时,请避免使用PerlCritic

Alb*_*ert 1 perl interpolation perl-critic

perlcritic在下面的代码的第一个评估线上抱怨表达形式为"eval"[BuiltinFunctions :: ProhibitStringyEval]:

use strict;
use warnings;
use feature qw/say/;

my $hasTwitter = 1;
my $validEmail = 0;

my $rule   = '${hasTwitter} | ${validEmail}';
my $result = eval $rule;
say "Result ->  $result";

$result = eval { $rule };
say "Result -> $result";
Run Code Online (Sandbox Code Playgroud)

我尝试使用eval {}来修复perlCritic但是它不会返回预期的结果.

回应是:

Result ->  1
Result -> ${hasTwitter} | ${validEmail}
Run Code Online (Sandbox Code Playgroud)

是否有使用字符串插值的解决方法?我们的想法是在配置文件上有一组规则,让代码读取并评估它们.

谢谢

ike*_*ami 6

评论家会让你想到:表达是否有理由作为一个字符串存在?鉴于众多陷阱和高安全隐患,是否可以避免这种情况?或者更确切地说,风险和问题是否值得避免一些工作?

首先,您可以使用以下内容吗?

my $rule = sub { $hasTwitter || $validEmail };

my $result = $rule->();
Run Code Online (Sandbox Code Playgroud)

或者可能

my $rule = 'has_twitter_or_email';

my %rules = (
   has_twitter_or_email => sub { $hasTwitter || $validEmail },
);
my $result = $rules{$rule}->();
Run Code Online (Sandbox Code Playgroud)

  • @simbabque,这就是为什么我没有说"你应该使用以下".在这种情况下,最好创建一个规则定义语言.配置文件不适用于Perl代码. (3认同)

sim*_*que 5

可以为特定块关闭单独的 Perl::Critic 规则。添加这样的评论。请注意,双重评论##是故意的。

my $rule   = '${hasTwitter} | ${validEmail}';

## no critic 'ProhibitStringyEval'
my $result = eval $rule;
Run Code Online (Sandbox Code Playgroud)

由于这适用于每个块,因此您将希望在尽可能小的范围内进行操作,就像 auseno

在评论中解释你为什么这样做是有道理的。通常,您的团队有充分的理由来选择规则,只有在您对特定情况有更好的理由时才应该关闭它们。