Почему эта программа действительна? Я пытался создать синтаксическую ошибку
Я запускаю 32 бит ActiveState ActivePerl 5.14.2 на Windows 7. Я хотел возиться с крючком предварительной фиксации Git для обнаружения программ, которые проверяются с синтаксическими ошибками. (Как-то мне просто удалось сделать такую плохую фиксацию.) Так как тестовая программа я случайно набросал это:
use strict;
use warnings;
Syntax error!
exit 0;
однако он компилируется и выполняется без предупреждений, а errorlevel равен нулю при выходе. Как это допустимый синтаксис?
5 ответов:
Perl имеет синтаксис, называемый "косвенный метод нотации". Это позволяет
Foo->new($bar)
писать так:
new Foo $bar
значит
Syntax error ! exit 0;
это то же самое, что
error->Syntax(! exit 0);
или
error->Syntax(!exit(0));
это не только допустимый синтаксис, это не приводит к ошибке во время выполнения, потому что первое, что выполняется
exit(0)
.
Я не знаю, почему, но это то, что Perl делает из него:
perl -MO=Deparse -w yuck BEGIN { $^W = 1; } use warnings; use strict 'refs'; 'error'->Syntax(!exit(0)); yuck syntax OK
кажется, что парсер думает, что вы вызываете метод
Syntax
наerror
-объект... Действительно странно!
причина, по которой вы не получаете ошибку, заключается в том, что первый выполненный код
exit(0);
потому что у вас не было точки с запятой в первой строке:
Syntax error!
компилятор догадается (неверно), что это вызов подпрограммы с
not
оператор!
сбросить. Затем он будет выполнять аргументы этой подпрограммы, которая оказываетсяexit(0)
, в этот момент программа завершает работу и устанавливает errorlevel в 0. Ничего больше не выполняется, поэтому больше нет времени выполнения сообщать об ошибках.Вы заметите, что если вы измените
exit(0)
что-то вродеprint "Hello world!"
вы получаете сообщение об ошибке:Can't locate object method "Syntax" via package "error" ...
и ваш уровень ошибки будут установлены:
> echo %errorlevel% 255
как отмечалось выше, это вызвано косвенным методом, вызывающим нотацию. Вы можете предупредить об этом:
use strict; use warnings; no indirect; Syntax error! exit 0;
выдает:
Indirect call of method "Syntax" on object "error" at - line 5.
для этого требуется косвенный модуль CPAN.
вы также можете использовать
no indirect "fatal";
чтобы заставить программу умереть (это то, что я делаю)
попробовать Perl 6, кажется, чтобы выполнить ваши ожидания более охотно:
===SORRY!=== Error while compiling synerror.p6 Negation metaoperator not followed by valid infix at synerror.p6:1 ------> Syntax error!⏏<EOL> expecting any of: infix infix stopper