Зачем использовать строгие и предупреждения?

92

Мне кажется, что многие вопросы в теге Perl могут быть решены, если люди будут использовать:

use strict;
use warnings;

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

Кажется, что большинство людей, владеющих Perl, всегда используют эти две прагмы, тогда как те, кто больше всего выиграет от их использования, редко делают. Итак, я подумал, что было бы неплохо связать вопрос, когда поощряя людей к use strict и warnings.

Итак, зачем разработчику Perl use strict и warnings?

  • 14
    Я всегда задаюсь вопросом о таких вещах, как то, почему они не просто делают это по умолчанию, и у разработчика фактически есть необходимость активно ослаблять вещи, где use loose;
  • 0
    Я никогда не слышал, чтобы кто-нибудь называл их тренировочными колесами; это всего лишь механизмы, позволяющие избежать попадания в ногу. Они должны быть действительно запечены в языке, чтобы их нельзя было выключить.
Показать ещё 12 комментариев
Теги:

8 ответов

75
Лучший ответ

Для начала use strict; (и, в меньшей степени, use warnings;) помогает найти опечатки в именах переменных. Такие опытные программисты делают такие ошибки. Обычным случаем является забывание переименовать экземпляр переменной при очистке или рефакторинге кода.

Использование use strict; use warnings; ломает много ошибок раньше, чем они будут пойманы иначе, что упростит поиск основных причин ошибок. Коренной причиной может быть необходимость проверки ошибок или проверки, и это может произойти независимо от умения программиста.

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


Связанное чтение: Зачем использовать my?

  • 2
    @TLP, я не собираюсь проводить исследование, чтобы определить, насколько это помогает. Достаточно сказать, что они помогают безоговорочно.
  • 1
    Почему это становится необязательным, если оно имеет так много преимуществ? Почему бы не включить его по умолчанию (как кто-то прокомментировал выше)? Это из соображений совместимости?
Показать ещё 2 комментария
26

По-видимому, use strict должен (должен) использоваться, когда вы хотите принудительно принудительно использовать perl для кода, который мог бы форсировать объявление, будучи явным для строк и подтипов i.e., или использовать ссылки с осторожностью. Примечание: если есть ошибки, использование строкой отменяет выполнение, если используется.

Пока use warnings; поможет вам найти ошибки ввода в программе, например, вы пропустили точку с запятой, вы использовали "elseif", а не "elsif", вы используете устаревший синтаксис или функцию, как бы то ни было. Примечание: использование предупреждений будет предоставлять предупреждения и продолжать выполнение, т.е. не отменяет выполнение.

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

Из perl.com (мой любимый):

используйте строгие 'vars';

что означает, что вы должны всегда объявлять переменные перед их использованием.

Если вы не объявите, вы, вероятно, получите сообщение об ошибке для необъявленной переменной

Глобальный символ "$ varablename" требует явного имени пакета в строке scriptname.pl 3

Это предупреждение означает, что Perl не совсем ясно, что такое переменная. Поэтому вам нужно четко указать свои переменные, что означает либо объявить их с помощью my, чтобы они были ограничены текущим блоком, либо ссылались на них с их полным именем (для ex: $MAIN:: variablename).

Итак, ошибка времени компиляции запускается, если вы пытаетесь получить доступ к переменной, которая не выполнила хотя бы один из следующих критериев:

  • Предопределено самим Perl, таким как @ARGV,% ENV и всеми глобальными переменными пунктуации, такими как $. или $_.

  • Объявлено с нашим (для глобального) или my (для лексического).

  • Импортировано из другого пакета. (Использование vars pragma подталкивает импорт, но использует наш вместо этого.)

  • Полностью квалифицируется с использованием имени пакета и разделителя пакетов с двойной колонкой.

использовать строгие 'subs';

Рассмотрим две программы

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program result: test passed

В обоих случаях у нас есть test_value(), и мы хотим поместить его результат в $a. И все же, когда мы запускаем две программы, мы получаем два разных результата:

В первой программе, в точке, которую мы получаем до $a = test_value;, Perl не знает ни одного элемента test_value(), а test_value интерпретируется как строка test_value. Во второй программе определение test_value() предшествует строке $a = test_value;. Perl считает, что test_value является подзаголовком.

Технический термин для изолированных слов, таких как test_value, которые могут быть subs и может быть строками, в зависимости от контекста, между прочим, является bareword. Обработка Perl barewords может сбивать с толку, и это может вызвать ошибку в программе.

Ошибка, с которой мы столкнулись в нашей первой программе. Помните, что Perl не ожидает поиска test_value(), так как он еще не видел test_value(), он предполагает, что вам нужна строка. Поэтому, если вы use strict subs;, это заставит эту программу умереть с ошибкой:

Bareword "test_value" не допускается, пока используются "строгие субтитры". /a 6-strictsubs.pl строка 3.

Решение этой ошибки будет 1. Используйте круглые скобки, чтобы было ясно, что вы вызываете sub. Если Perl видит $a = test_value();,
2. Объявите свой юнит перед его первым использованием.

use strict;
sub test_value;  # Declares that there a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. И если вы хотите использовать его в виде строки, процитируйте ее.

Итак, эта стриктура заставляет Perl рассматривать все слова как синтаксические ошибки. * Говорное слово - любое голое имя или идентификатор, который не имеет другой интерпретации, вызванной контекстом. (Контекст часто заставляют соседнее ключевое слово или токен, или путем предопределения рассматриваемого слова.) * Итак, если вы хотите использовать его как строку, процитируйте его, и если вы хотите использовать его в качестве вызова функции, представьте его или используйте круглые скобки.

Баги опасны из-за этого непредсказуемого поведения. use strict; (or use strict 'subs';) делает их предсказуемыми, потому что голые слова, которые могут вызвать странное поведение в будущем, заставят вашу программу умереть, прежде чем они смогут нанести ущерб

Там одно место, где можно использовать открытые слова, даже если вы включили строгие субтитры: когда вы назначаете хеш-ключи.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

Бары в хэш-ключах всегда интерпретируются как строки, поэтому нет никакой двусмысленности.

использовать строгие 'refs';

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

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

использовать предупреждения;

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

От perldiag:

Таким образом, большинство предупреждающих сообщений из классификаций ниже, а именно W, D и S, можно управлять с помощью warnings прагмы.

(W) Предупреждение (необязательно)
(D) Отклонение (включено по умолчанию)
(S) Серьезное предупреждение (включено по умолчанию)

Я перечислил некоторые сообщения о предупреждениях, которые часто встречаются ниже классификациями. Для получения подробной информации о них и других сообщениях обратитесь perldiag

(W) Предупреждение (необязательно):

Отсутствует аргумент в% s
Отсутствует аргумент -% c
(Вы имели в виду &% s вместо?)
(Вы имели в виду "локальный", а не "наш"?)
(Вы имели в виду $или @вместо%?)
'% s' не является ссылкой на код length() используется на% s
Неверное _ число

(D) Уступка (включена по умолчанию):

defined (@array) устарел
определенный (% hash) устарел
Устаревшее использование my() в ложном условном выражении $# больше не поддерживается

(S) Серьезное предупреждение (включено по умолчанию)

elseif должен быть elsif
% s найдено, где оператор ожидал
(Отсутствует оператор до% s?)
(Отсутствует точка с запятой на предыдущей строке?)
% s никогда не вводится
Оператор или точка с запятой отсутствует до% s
Проблема приоритета: открыть% s должен быть открыт (% s)
Несоответствие прототипа:% s vs% s
Предупреждение: использование "% s" без круглых скобок неоднозначно
Не удается открыть% s:% s

10

Эти две прагмы могут автоматически идентифицировать ошибки в вашем коде.

Я всегда использую это в своем коде:

use strict;
use warnings FATAL => 'all';

FATAL заставляет код умирать от предупреждений, как это делает strict.

Дополнительную информацию см. в разделе Усилить использование предупреждений FATAL = > 'all';

Также... Строки, согласно Сьюсу

  • 0
    На самом деле, вы должны отложить FATAL => "all" до времени выполнения, присваивая $SIG{__WARN__} = sub { croak "fatalized warning @_" }; или же вы испортите компилятор, пытаясь сказать вам, что ему нужно.
  • 6
    @tchrist: Это всегда работало для меня как есть и как задокументировано. Если вы обнаружили случай, когда он не работает так, как задокументировано, пожалуйста, perlbug документацию с помощью perlbug .
9

Там хороший поток на perlmonks об этом вопросе.

Основная причина, очевидно, в том, что строгие и предупреждающие сообщения в значительной степени помогают вам ошибаться и помогают отлаживать.

3

Источник:: Разные блоги

Использование будет экспортировать функции и имена переменных в основное пространство имен вызов функции import().

Прагма - это модуль, который влияет на некоторый аспект времени компиляции или время выполнения perl.Pragmas дают подсказки компилятору.

Использовать предупреждения - perl жалобы на переменные, используемые только один раз, неправильное преобразование строк в числа,.Trying to write to файлы, которые не открываются .it происходит во время компиляции. Используется для контрольные предупреждения.

Использовать строку strict - declare variables scope. Он используется для установки своего рода дисциплина в script. Если в коде используются только слова, интерпретируются. Все переменные должны быть заданы как для моего, так и для нашего локальные.

1

Директива "use strict" указывает Perl на дополнительную проверку во время компиляции вашего кода. Используя эту директиву, вы сэкономите время на отладку своего кода Perl, потому что он обнаруживает общие ошибки в кодировке, которые вы могли бы игнорировать в противном случае.

0
use strict;
use warnings;

Строго и предупреждения - это режим для программы perl. Это позволяет пользователю вводить код более либерально и более того, что код perl будет выглядеть формально, и его стандарт кодирования будет эффективным.

предупреждения означают то же самое, что и -w в строке perl shebang, поэтому он будет предоставит вам предупреждения, сгенерированные программой perl, отобразит в терминале

0

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

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

$_, или нет переменной для некоторых функций, также может быть полезно быстрее записать более компактный код.

Однако, если вы не используете строгие и предупреждающие сообщения, $_ становится глобальным!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню