Могу ли я «использовать предупреждения» только в одной подпрограмме? - PullRequest
4 голосов
/ 14 марта 2012

Я работаю над CGI-скриптом Perl, размером около 4000 строк. Наш стиль кодирования обычно включает use strict и use warnings, но в этом конкретном (довольно старом) файле закомментированы «предупреждения об использовании» с комментарием о том, что включение предупреждений приведет к заполнению журнала Apache.

Теперь я планирую разделить некоторый код на новую подпрограмму. Я хочу use warnings по крайней мере, там. Как можно безопасно ограничить эффект use warnings одной подпрограммой? Будет ли выполнять помещение условия use внутри подпрограммы?

Ответы [ 6 ]

13 голосов
/ 14 марта 2012

Да, использование use warning будет в той области, в которой вы его написали.

Запись use warning внутри подпрограммы будет влиять только на подпрограмму (или блок) подачи.


пример фрагмента

sub foo {
  use warnings;
  print  my $a; 
}

{
  use warnings;
  print  my $b;
}

foo;

print my $c;

выход

Use of uninitialized value $b in print at foo.pl line 8.
Use of uninitialized value $a in print at foo.pl line 3.

Обратите внимание, что предупреждение оиспользование print my $c.


Что говорится в документации?

  • perldoc.perllexwarn

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

4 голосов
/ 14 марта 2012

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

use warnings;

sub new_method {
  # shiny new code
}

sub old_method {
  no warnings;

  # nasty old code
}
3 голосов
/ 14 марта 2012

Да. От perldoc :

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

http://perldoc.perl.org/warnings.html

2 голосов
/ 14 марта 2012

Ответ, что use warnings можно использовать лексически, является правильным. Решение использовать no warnings лексически и use warnings глобально является более правильным. Корректное решение состоит в том, чтобы исправить все ваши предупреждения. Где-то посередине лежит перенаправление ошибок.

use warnings;
open STDERR, ">>", "foo/error.log" or die $!;

Оставьте это на некоторое время, затем выполните:

perl -nlwe '$a{$_}++ }{ print for keys %a' foo/error.log > foo/errors.dedupe

Пройдите код и исправьте предупреждения. Скорее всего, если скрипт работает, они будут тривиальными. Но если вы не проверите, откуда вы знаете?

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

2 голосов
/ 14 марта 2012

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

Вам не нужно помещать use warnings; или no warnings; внутри каждого sub.Вы можете создавать специальные области видимости, используя фигурные скобки, например.

use warnings;

sub nice_new_sub_1 { ... }

sub nice_new_sub_2 { ... }

{
    no warnings;

    sub nasty_old_sub_3 { ... }

    sub nasty_old_sub_4 { ... }

    sub nasty_old_sub_5 { ... }
}

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

{
    no strict 'refs';

    sub nasty_old_sub_3 { ... }

    sub nasty_old_sub_4 { ... }
}
.
2 голосов
/ 14 марта 2012

Только что нашел ответ сам в "perldoc perllexwarn":

...the scope of the warning pragma is limited to the enclosing block.

Так должно работать следующее:

sub new_method {
    use warnings;
    ...
}

sub old_method {
    ... # no warnings here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...