519

Windows7でActiveStateの32ビットActivePerl5.14.2を実行しています。構文エラーでチェックインされているプログラムを検出するために、Gitpre-commitフックをいじりたいと思いました。(どういうわけか、私はなんとかそのような悪いコミットを行うことができました。)それで、テストプログラムとして、私はこれをランダムに書きました:

use strict;
use warnings;

Syntax error!

exit 0;

ただし、警告なしでコンパイルおよび実行され、終了時のエラーレベルはゼロです。この有効な構文はどうですか?

4

6 に答える 6

568

Perlには、「間接メソッド表記」と呼ばれる構文があります。それは可能にします

Foo->new($bar)

として書かれる

new Foo $bar

つまり、

Syntax error ! exit 0;

と同じです

error->Syntax(! exit 0);

また

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

有効な構文であるだけでなく、最初に実行されるのはであるため、実行時エラーは発生しませんexit(0)

于 2012-07-27T20:36:00.930 に答える
117

理由はわかりませんが、これがPerlによるものです。

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

Syntaxパーサーは、オブジェクトのメソッドを呼び出していると考えているようですerror...確かに奇妙です!

于 2012-07-27T20:26:55.417 に答える
56

エラーが発生しない理由は、最初に実行されたコードが

exit(0);

最初の行にセミコロンがなかったため:

Syntax error!

notコンパイラは、これが演算子がスローされたサブルーチン呼び出しであると(誤って)推測!します。次に、このサブルーチンへの引数を実行します。これはたまたまでありexit(0)、その時点でプログラムは終了し、エラーレベルを0に設定します。他には何も実行されません。 、したがって、これ以上ランタイムエラーは報告されません。

exit(0)次のようなものに変更するとprint "Hello world!"、エラーが発生することに気付くでしょう。

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

エラーレベルが設定されます:

> echo %errorlevel%
255
于 2012-07-27T20:36:41.493 に答える
35

上記のように、これは表記法を呼び出す間接的なメソッドによって引き起こされます。これについて警告することができます:

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";(これが私が行うことです)

于 2014-04-03T14:07:28.740 に答える
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
于 2016-02-05T21:00:05.500 に答える
3

この論文では、プログラミング言語コミュニティで長年開かれている問題に答えることを目指しています。有効なPerlを作成せずに壁にペンキを塗ることは可能ですか?

TLDR; しそうにない

于 2020-01-05T14:22:17.543 に答える