2014-02-03 3 views
3

Я хочу иметь фатальные ошибки, которые могут быть понижены до предупреждений (или, наоборот, предупреждения, которые могут быть распространены на фатальные ошибки) в зависимости от предпочтений пользователя. В настоящее время я использую die и опрокинув его, как это:Как я могу условно сделать предупреждения фатальными?

my $force; 
BEGIN { 
    no warnings 'once'; 
    Getopt::Long::Configure('pass_through'); 
    GetOptions('force', \$force); 
    *CORE::GLOBAL::die = sub { warn @_ } if $force; 
    Getopt::Long::Configure('no_pass_through'); 
} 

use My::Module; 
... 
die "maybe"; 
... 
exit(1) if $force; 
exit(0); # success! 

мне не нравится этот подход, в основном, потому что есть несколько мест, где я все равно хочу умереть (например, недостающие аргументы командной строки) , Я предпочел бы изменить (наиболее) экземпляры die на warn и сделать условное use warnings FATAL => 'all' . Проблема заключается в том, что use warnings является лексическую область видимости, так что это неэффективно:

if (!$force) { 
    use warnings FATAL => 'all'; 
} 

Попытка использовать постфикс условный синтаксическая ошибка:

use warnings FATAL => 'all' unless $force; 

и use не могут быть использованы в выражении:

$force or use warnings FATAL => 'all'; # syntax error 

я могу думать о различном неприятных обходных (Определении пара предупредит/умереть, дублируя мой основной код сценария в если/другое, и т.д.), но ищет элегантное решение, которое условно применяет use warnings в текущей лексической области. (Применяя его в родительской области будет работать хорошо, но, вероятно, потребует темную магию.)


1: На самом деле, я хочу, чтобы добавить use warnings::register в мои модули и use warnings FATAL => 'My::Module' к моему сценарию, но это различие несущественно цели этого вопроса.

+1

Немного кривой обучения, но, вы видели [Log4perl] (http://search.cpan.org/~mschilli/Log-Log4perl/)? – user3183018

ответ

4

Вы можете попробовать:

use if !$force, warnings => qw(FATAL all); 

Да, есть модуль, который называется if, который распространяется с Perl, чтобы сделать это очень легко сделать условный импорт.

Обратите внимание, что это оценивается в времени компиляции, поэтому $force необходимо определить во время компиляции. (Вероятно, в блоке BEGIN { ... }.) Основываясь на образцах кода в вашем вопросе, вы, похоже, уже поняли, что часть уже есть.

В качестве альтернативы, более ручная:

BEGIN { 
    require warnings; 
    warnings->import(qw/ FATAL all /) unless $force; 
} 

Совершенно иной подход будет использовать обработчик сигнала $SIG{__WARN__} или $SIG{__DIE__}, чтобы решить, чтобы умереть или нет во время выполнения.

Смежные вопросы