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

时间:2012-07-27 20:19:23

标签: perl

我在Windows 7上运行ActiveState的32位ActivePerl 5.14.2。我想要使用Git预提交挂钩来检测正在检查的语法错误的程序。 (不知怎的,我只是设法做了这么糟糕的提交。)所以作为一个测试程序,我随机记下了这个:

use strict;
use warnings;

Syntax error!

exit 0;

但是,它在没有警告的情况下编译并执行,退出时errorlevel为零。这个有效的语法怎么样?

6 个答案:

答案 0 :(得分:526)

Perl的语法称为“间接方法表示法”。它允许

Foo->new($bar)

写成

new Foo $bar

这意味着

Syntax error ! exit 0;

相同
error->Syntax(! exit 0);

error->Syntax(!exit(0));

它不仅是有效的语法,而且不会导致运行时错误,因为执行的第一件事是exit(0)

答案 1 :(得分:108)

我不知道为什么,但这就是Perl所做的:

perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK

似乎解析器认为你在​​Syntax - 对象上调用方法error ......确实很奇怪!

答案 2 :(得分:52)

您没有收到错误的原因是第一个执行的代码是

exit(0);

因为第一行没有分号:

Syntax error!

编译器会猜测(错误地)这是一个抛出了not运算符!的子例程调用。然后它将执行此子例程的参数,恰好是{{1}程序退出并将errorlevel设置为0.此时不会执行任何其他操作,因此不会报告更多的运行时错误。

您会注意到,如果您将exit(0)更改为exit(0)之类的内容,则会收到错误消息:

print "Hello world!"

并设置错误级别:

Can't locate object method "Syntax" via package "error" ...

答案 3 :(得分:33)

如上所述,这是由间接方法调用符号引起的。你可以警告:

use strict;
use warnings;
no indirect;

Syntax error!

exit 0;

产地:

Indirect call of method "Syntax" on object "error" at - line 5.

这需要indirect CPAN module

您也可以使用no indirect "fatal";导致程序死亡(这就是我所做的)

答案 4 :(得分:7)

尝试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

答案 5 :(得分:1)

在此paper中,我们旨在回答长期存在的公开问题 编程语言社区:是否有可能在 墙而没有创建有效的Perl?

TLDR;几乎没有