我在Windows 7上运行ActiveState的32位ActivePerl 5.14.2.我想用Git预提交钩子来检测正在检查的语法错误的程序.(不知怎的,我只是设法做了这么糟糕的提交.)所以作为一个测试程序,我随机记下了这个:
use strict;
use warnings;
Syntax error!
exit 0;
Run Code Online (Sandbox Code Playgroud)
但是,它在没有警告的情况下编译和执行,退出时errorlevel为零.这个有效的语法怎么样?
ike*_*ami 536
Perl有一种称为"间接方法表示法"的语法.它允许
Foo->new($bar)
Run Code Online (Sandbox Code Playgroud)
写成
new Foo $bar
Run Code Online (Sandbox Code Playgroud)
这意味着
Syntax error ! exit 0;
Run Code Online (Sandbox Code Playgroud)
是相同的
error->Syntax(! exit 0);
Run Code Online (Sandbox Code Playgroud)
要么
error->Syntax(!exit(0));
Run Code Online (Sandbox Code Playgroud)
它不仅是有效的语法,它不会导致运行时错误,因为执行的第一件事是exit(0)
.
pav*_*vel 109
我不知道为什么,但这就是Perl所做的:
perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK
Run Code Online (Sandbox Code Playgroud)
似乎解析器认为你在-object Syntax
上调用方法error
......确实是奇怪的!
TLP*_*TLP 53
您没有收到错误的原因是第一个执行的代码是
exit(0);
Run Code Online (Sandbox Code Playgroud)
因为第一行没有分号:
Syntax error!
Run Code Online (Sandbox Code Playgroud)
编译器会猜测(错误地)这是一个带有not
操作符的子程序调用!
.然后它将执行该子程序的参数,恰好是exit(0)
程序退出并将errorlevel设置为0.其他任何执行都没有执行,因此不再报告运行时错误.
您会注意到,如果您更改exit(0)
为类似的内容,print "Hello world!"
则会收到错误消息:
Can't locate object method "Syntax" via package "error" ...
Run Code Online (Sandbox Code Playgroud)
并将设置您的错误级别:
> echo %errorlevel%
255
Run Code Online (Sandbox Code Playgroud)
Mar*_*ler 33
如上所述,这是由间接方法调用符号引起的.你可以警告:
use strict;
use warnings;
no indirect;
Syntax error!
exit 0;
Run Code Online (Sandbox Code Playgroud)
生产:
Indirect call of method "Syntax" on object "error" at - line 5.
Run Code Online (Sandbox Code Playgroud)
这需要间接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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23588 次 |
最近记录: |