我在Windows 7上运行ActiveState的32位ActivePerl 5.14.2。我想玩一下Git的预提交挂钩,以检测被检入的程序是否存在语法错误。(不知何故,我刚刚犯了这样一个糟糕的提交)。因此,作为测试程序,我随机写下了以下内容:
use strict;
use warnings;
Syntax error!
exit 0;
然而,它能够编译并且执行没有警告,退出时errorlevel为零。这是如何有效的语法?
我在Windows 7上运行ActiveState的32位ActivePerl 5.14.2。我想玩一下Git的预提交挂钩,以检测被检入的程序是否存在语法错误。(不知何故,我刚刚犯了这样一个糟糕的提交)。因此,作为测试程序,我随机写下了以下内容:
use strict;
use warnings;
Syntax error!
exit 0;
然而,它能够编译并且执行没有警告,退出时errorlevel为零。这是如何有效的语法?
Foo->new($bar)
写成
new Foo $bar
Syntax error ! exit 0;
与
error->Syntax(! exit 0);
或者
error->Syntax(!exit(0));
不仅是有效的语法,而且它不会导致运行时错误,因为首先执行的是 exit(0)
。
此功能可以通过以下任何一种方式禁用:
no feature qw( indirect ); # Perl 5.32+
use v5.36; # Perl 5.36+
no indirect; # CPAN module
exit
的返回值是布尔值(或其他可以成为!
操作数的内容)时,才能起作用,即仅仅是一个表达式是不够的。 - user377628!exit(0)
和!$x
都没有类型错误,因为它们都没有类型。 - ikegaminew Class
和print $fh ...
而不是Class->new(...)
和$ fh->print(...)
的Perl程序员中都会使用它。我承认它会导致奇怪的错误消息,但这也是它的特点。 - ikegami我不知道为什么,但这就是Perl的结果:
perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK
看起来解析器认为你在error
对象上调用了Syntax
方法...这确实很奇怪!
exit(0)
先被评估,使程序在尝试将结果传递给'error'->Syntax()
之前退出。 - user149341new Class
而不是Class->new()
。为了调用方法Syntax
,执行了exit
函数,因此运行时错误从未发生。 - amonexit(0);
Syntax error!
!
的子例程调用。然后,它将执行这个子例程的参数,这恰好是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.
这需要使用indirect CPAN模块。
你也可以使用no indirect "fatal";
让程序崩溃(这是我的做法)
use v.5:32; no feature 'indirect';
- Rsh试试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
whatever / 25 ; # / ; die "this dies!";
- clt60