Почему эта программа действительна? Я пытался создать синтаксическую ошибку

Я запускаю ActiveState 32-разрядный ActiveSter 5.14.2 ActiveState в Windows 7. Я хотел пообщаться с Git pre-commit hook для обнаружения программ, проверяемых с синтаксическими ошибками. (Как-то мне просто удалось сделать такую ​​плохую фиксацию.) Так что, как тестовая программа, я случайно записал это:

use strict; use warnings; Syntax error! exit 0; 

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

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) , после чего программа выйдет и установит уровень ошибок равным 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!⏏ expecting any of: infix infix stopper 
  • Как я могу анализировать даты и преобразовывать часовые пояса в Perl?
  • Регулярное выражение соответствует любому символу, включая новые строки
  • Использование 'use utf8;' дает мне «Широкий характер в печати»,
  • Регулярное выражение Perl (с использованием переменной в качестве строки поиска с включенными символами оператора Perl)
  • Как сравнить две строки в Perl?
  • Почему мои тесты на Perl терпят неудачу с `use encoding 'utf8'`?
  • Как я могу подключиться к печати в Perl?
  • Какое регулярное выражение может соответствовать последовательностям одного и того же символа?
  • Как я могу взаимодействовать с ClearCase с Perl?
  • Что значит !! (двойной восклицательный знак) означает?
  • Разница между & function и функцией () в perl
  • Давайте будем гением компьютера.