繁体   English   中英

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

[英]Why is this program valid? I was trying to create a syntax error

我在 Windows 7 上运行 ActiveState 的 32 位ActivePerl 5.14.2。我想弄乱一个 Git 预提交钩子来检测被签入的程序是否有语法错误。 (不知何故,我只是设法做了一个如此糟糕的提交。)所以作为一个测试程序,我随机记下了这个:

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

解析器似乎认为您正在对error -object 调用方法Syntax ......确实很奇怪!

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

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";使用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

本文中,我们旨在回答编程语言社区中一个长期存在的悬而未决的问题:是否可以在不创建有效 Perl 的情况下在墙上涂抹油漆?

TLDR; 几乎不

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM