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

时间:2015-09-23 15:38:16

标签: 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";

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

回复是:

Result ->  1
Result -> ${hasTwitter} | ${validEmail}

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

由于

3 个答案:

答案 0 :(得分:6)

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

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

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

my $result = $rule->();

或者

my $rule = 'has_twitter_or_email';

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

答案 1 :(得分:4)

can turn individual Perl::Critic rules off了解特定区块。添加这样的评论。请注意,双重评论##是故意的。

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

## no critic 'ProhibitStringyEval'
my $result = eval $rule;

由于这适用于每个块,因此您需要在尽可能小的范围内执行此操作,就像useno一样。

在评论中解释为什么你这样做是有意义的。通常你的团队有充分的理由选择规则,如果你有更好的理由来解决你的具体案例,你应该只关闭它们。

答案 2 :(得分:1)

Perlcritic不是最终权威。如果您知道自己在做什么以及为什么,只需禁用给定的“sin”(在配置中全局,或者将## no critic添加到有问题的行中)。

在这种情况下,您可以使用双引号而不是单引号,并在评估它们之前验证结果字符串中只有零和1。实现逻辑公式的解析器和评估器也不是那么难。