Подтвердить что ты не робот

Как я должен рекламировать предупреждения Perl для фатальных ошибок во время разработки?

При запуске набора тестовых приложений для приложений я хочу распространять все предупреждения компиляции и времени выполнения Perl (например, предупреждение "Неинициализированная переменная" ) на фатальные ошибки, чтобы я и другие разработчики исследовали и исправляли код, генерирующий предупреждение. Но я хочу делать это только во время разработки и тестирования CI. В производстве предупреждения должны оставаться в качестве предупреждений.

Я пробовал следующее: В "t/lib" я создал модуль TestHelper.pm:

# TestHelper.pm
use warnings FATAL => qw( all );
1;

Затем вызывается тестовый набор следующим образом:

$ PERL5LIB=$PERL5LIB:./t/lib PERL5OPT=-MTestHelper.pm prove -l t/*.t

Но это не имело желаемого эффекта от распространения всех предупреждений на фатальные ошибки. Я получил предупреждения как обычно, но предупреждения, похоже, не считались фатальными. Обратите внимание, что все мои сценарии test.t имеют строку "use warnings"; в них - возможно, это превысит одно в TestHelper.pm, потому что "использование предупреждений" имеет локальную область?

Вместо этого я сделал это:

# TestHelper.pm
# Promote all warnings to fatal 
$SIG{__WARN__} = sub { die @_; };
1;

Это работает, но имеет запах кода. Мне также не нравится, что он бомбит первое предупреждение. Я бы предпочел, чтобы тестовый набор работал полностью, регистрируя все предупреждения, но что состояние теста в конечном итоге не удалось, потому что код работал с предупреждениями.

Есть ли лучший способ достичь этого конечного результата?

4b9b3361

Ответ 2

Причина use warnings FATAL => qw( all ); не работает для вас, потому что use warnings лексически ограничен. Поэтому любые предупреждения, произведенные внутри TestHelper.pm, будут смертельными, но предупреждения, созданные в другом месте, будут работать как обычно.

Если вы хотите включить смертельные предупреждения по всему миру, я думаю, что обработчик $SIG{__WARN__}, вероятно, единственный способ сделать это. Если вы не хотите, чтобы он взорвался при первом предупреждении, вы можете оставить свой обработчик в массиве, а затем проверить его в блоке END.

my @WARNINGS;
$SIG{__WARN__} = sub { push @WARNINGS, shift };

END { 
    if ( @WARNINGS )  {       
        print STDERR "There were warnings!\n";
        print "$_\n" for @WARNINGS;
        exit 1;
    }
}