Избегайте PerlCritic при интерполяции переменных с помощью eval

perlcritic жалуется с помощью формы выражения "eval" [BuiltinFunctions::ProhibitStringyEval] в первой строке eval из кода ниже:

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 ответа

Критик здесь, чтобы заставить вас задуматься: есть ли причина, чтобы выражение было в виде строки? Можно ли этого избежать, учитывая многочисленные подводные камни и высокие риски безопасности? Или, скорее, стоит ли избегать небольшой работы с рисками и проблемами?

Для начала, вы могли бы использовать следующее?

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}->();

Вы можете отключить отдельные правила Perl:: Critic для определенных блоков. Добавьте комментарий как это. Обратите внимание на двойной комментарий ## нарочно.

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

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

Поскольку это работает для каждого блока, вы захотите сделать это в наименьшем объеме, как use или же no,

Имеет смысл объяснить в комментарии, почему вы это сделали. Обычно у вашей команды есть веские причины для выбора правил, и вы должны отключать их только в том случае, если у вас есть более веская причина для вашего конкретного случая.

Perlcritic не является высшим авторитетом. Если вы знаете, что делаете и почему, просто отключите данный "грех" (либо глобально в конфигурации, либо добавив ## no critic на оскорбительную линию).

В этом случае вы можете использовать двойные кавычки вместо одинарных кавычек и убедиться, что в результирующих строках есть только нули и единицы, прежде чем их оценивать. Реализовать синтаксический анализатор и анализатор логических формул тоже не сложно.

Другие вопросы по тегам