为什么这个程序有效? 我试图创build一个语法错误

我在Windows 7上运行32位的ActiveState 5.14.2。我想混乱一个git pre-commit钩子来检测正在检查的语法错误的程序。 (不知怎的,我只是设法做了这样一个不好的承诺。)所以作为一个testing程序,我随机记下这个:

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

但是,它编译和执行时没有警告,出错时errorlevel为零。 这个有效的语法如何?

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 

看起来,parsing器认为你正在调用方法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