Может использовать строгое предупреждение вместо ошибки - PullRequest
4 голосов
/ 25 марта 2011

При использовании use strict perl генерирует ошибку времени выполнения на небезопасных конструкциях. Теперь мне интересно, можно ли сделать так, чтобы он выводил только предупреждение, а не вызывал ошибку во время выполнения? Или use warnings (или -w) предупреждает о тех же проблемах?

Ответы [ 5 ]

14 голосов
/ 25 марта 2011

Нет, use strict нельзя заставить предупреждать, а не умирать.Все, что он делает, это устанавливает несколько битов в магическую переменную $^H, которая вызывает различные вещи в кишечнике интерпретатора Perl.

Нет, use warnings не предупреждает о тех же вещах, что и use strict убивает тебя за.Например, use warnings предупредит вас о переменных, используемых только один раз (что может быть результатом опечаток).

4 голосов
/ 29 марта 2011

Я попытаюсь угадать реальную мотивацию здесь. Не стесняйтесь сказать мне, если я угадал.

Я подозреваю, что вы пытаетесь заняться большой, более старой кодовой базой и хотели бы включить ограничения, но вы сначала надеялись получить представление о том, где будут ошибки (и сколько их будет) без нарушения функциональности. К сожалению, поскольку use strict функционирует путем изменения внутреннего поведения синтаксического анализатора и интерпретатора perl, не существует «строгого строгого» или, по аналогии с html, какого-либо «переходного» режима.

Однако вы можете отделить функциональность use strict, чтобы начать движение в правильном направлении. Во-первых, обратите внимание, что на самом деле есть три отдельные части:

use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords

и из этих только 'refs' выдает ошибки во время выполнения. Таким образом, вы можете легко добавить use strict qw(vars subs) к каждому из ваших файлов (скриптов и модулей) и протестировать их с помощью perl -c. Если вы обнаружите какие-либо сообщения об ошибках, закомментируйте use strict или, по крайней мере, одну из двух неудачных проверок, добавьте комментарий о характере ошибки и продолжайте. Таким образом, вы можете быстро (в зависимости от количества файлов) определить, какие файлы имеют ошибки во время компиляции, и вернуться к ним позже. (Если бы вы были более мотивированы, чем я в данный момент, вы могли бы даже автоматизировать этот процесс). Если у вас нет кода, который делает страшные вещи внутри BEGIN блоков, это должно быть довольно безопасно.

Более сложная часть заключается в проверке ошибок времени выполнения, генерируемых use strict 'refs', и, к сожалению, на самом деле не существует простого способа сделать это, потому что ошибки вызываются символьными ссылками, которые не могут быть определены никаким видом статики. анализ, так что -c и / или Perl :: Critic бесполезны.

Надеюсь, это приблизит вас к решению вашей реальной проблемы.

4 голосов
/ 25 марта 2011

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

{
    no strict 'refs';
    # symrefs okay within this block
}

Предупреждения также можно отключить лексически (при условии, что вы сделали use warnings вместо в значительной степени устаревшего флага -w).

Стриктуры и предупреждения обеспечивают безопасность. Вот почему их рекомендуется использовать по умолчанию. Если вы отключите их, вам следует отключить только то, что необходимо, и ограничить изменение до минимально возможного диапазона.

3 голосов
/ 25 марта 2011

Предпочтительный метод:

use Carp;

sub foo {
  croak "no args" unless @_;
}

eval foo();
if( $@ ){
  print "caught die: $@";
}

Если вы не можете изменить die на croak:

sub foo {
  die "no args" unless @_;
}

{
  my $prev_die = $SIG{__DIE__};
  $SIG{__DIE__} = sub { print "caught die: $_[0]"; };
  eval foo();
  $SIG{__DIE__} = $prev_die;
}

Второй метод выведет на печатьошибки в STDERR.

См .:

perldoc -f eval

perldoc perlvar и поиск /\$\@/ и /__DIE__/

perldoc Carp

1 голос
/ 25 марта 2011

Предупреждения могут быть сделаны фатальными - см. perllexwarn - но строгие ошибки не могут быть сделаны фатальными.

Почему вы хотите это сделать?Я подозреваю, что проблема XY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...