Ошибка Perl-критика при разбиении строки на массив с помощью регулярных выражений - PullRequest
0 голосов
/ 30 апреля 2018
sub func {
    my ($n) = @_;
    return unless ($n);
    my @array;
    push @array, $1 while $n =~ /
            ((?:
              [^(),]+ |
              ( \(
                (?: [^()]+ | (?2) )*
              \) )
            )+)
            (?: ,\s* | $)
            /xg;

    return \@array;
    }

    for my $item (@array) {
        if (index($item, '$n') != -1) {
           print "HELLO\n";
        }
} 

У меня есть вышеприведенное регулярное выражение для разбиения некоторой строки на массив. Работает нормально.

Проблема:

Критик Perl дает ниже ошибки. Посоветуйте, пожалуйста, как мне это исправить.

Capture variable used outside conditional at line 150, 
    near 'push @array, $1 while $n =~ /'.  (Severity: 3)
Use '{' and '}' to delimit multi-line regexps at line 150, 
    near 'push @input_expression, $1 while $n =~ /'.  (Severity: 1)
String *may* require interpolation at line 168, 
    near '$item, '$n''.  (Severity: 1)

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Perl Critic не выдает никаких ошибок. Это дает нарушения политики.

Чтобы исправить первый, измените цикл с модификатора на цикл while и назовите переменную:

    while ($n =~ /
        ...

    /xg) {
        my $match = $1;
        push @array, $match;
    }

Чтобы исправить второй, просто измените /.../ на m{...}.

По моему мнению, не имеет смысла использовать политики, которые вы плохо понимаете. Иногда могут быть очень веские причины сломать некоторые из них; слепое следование Perl Critic (особенно на более строгих уровнях) ничего вам не приносит.

0 голосов
/ 30 апреля 2018

Первый из них - это ложное срабатывание IMO, поскольку while действует здесь как условное условие - push @array, $1 не будет выполнено, пока не будет выполнено соответствие регулярному выражению, чего и хочет политика (добавьте --verbose 11 к perlcritic вызов, чтобы увидеть объяснения). Это тот случай, когда я думаю, что безопасно подавлять политику, как я покажу ниже.

Второй легко исправить, просто замените $n =~ /.../xg на $n =~ m{...}xg.

push @array, $1  ## no critic (ProhibitCaptureWithoutTest)
    while $n =~ m{ ... }xg;

Это подавляет эти два сообщения.

Как примечание: запуск perlcritic при brutal серьезности является IMO немного экстремальным, и он будет жаловаться на множество других вещей в этом фрагменте. Лично, когда я использую его, я запускаю perlcritic на harsh (-3) с несколькими политиками на настроенных уровнях.

Редактировать: Что касается вашего третьего perlcritic сообщения, которое вы добавили в свое сообщение позже, похоже, что на него ответили в вашем другом сообщении .

...