web-gelistirme-sc.com

Bu program neden geçerli? Bir sözdizimi hatası oluşturmaya çalışıyordum

Windows 7'de ActiveState 32 bit ActivePerl 5.14.2 kullanıyorum. Sözdizimi hataları ile kontrol edilen programları tespit etmek için Git ön işleme kancası ile uğraşmak istedim. (Her nasılsa ben sadece bu kadar kötü bir iş yapmayı başardım.) Bu yüzden bir test programı olarak bunu rastgele belirttim:

use strict;
use warnings;

Syntax error!

exit 0;

Ancak, hiçbir uyarı olmadan derler ve yürütür ve hata durumunda hata seviyesi sıfırdır. Bu nasıl sözdizimi geçerli?

486
Bill Ruppert

Perl'de "dolaylı yöntem notasyonu" adı verilen bir sözdizimi vardır. İzin veriyor

Foo->new($bar)

olarak yazılmak

new Foo $bar

Yani bu demek oluyor ki

Syntax error ! exit 0;

aynıdır

error->Syntax(! exit 0);

veya

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

Yalnızca geçerli sözdizimi değil, çalıştırılan ilk şey exit(0) olduğundan çalışma zamanı hatasıyla sonuçlanmaz.

534
ikegami

Nedenini bilmiyorum, ama Perl’in yaptığı şey bu:

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

Ayrıştırıcı Syntax- nesnesindeki error yöntemini çağırdığınızı düşünüyor gibi görünüyor ... Gerçekten de garip!

109
pavel

Hata alamamanın nedeni ilk çalıştırılan kodun

exit(0);

Çünkü ilk satırda noktalı virgül yoktu:

Syntax error!

Derleyici (yanlış) bunun, atılan bir not işleci ! ile bir alt yordam çağrısı olduğunu tahmin edecektir. Ardından, programın hangi noktasında exit(0) olan bu alt yordamın argümanlarını yerine getirecektir. çıkar ve hata seviyesini 0 olarak ayarlar. Başka hiçbir şey yapılmaz, bu nedenle başka çalışma zamanı hatası rapor edilmez.

exit(0) işlevini print "Hello world!" gibi bir şeyle değiştirirseniz hata alırsınız:

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

ve hata seviyen ayarlanacak:

> echo %errorlevel%
255
53
TLP

Yukarıda da belirtildiği gibi, bu, dolaylı yöntem çağrı notasyonundan kaynaklanmaktadır. Bu konuda uyarabilirsiniz:

use strict;
use warnings;
no indirect;

Syntax error!

exit 0;

Üretir:

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

Bu, dolaylı CPAN modülü gerektirir.

Programın ölmesine neden olmak için no indirect "fatal"; öğesini de kullanabilirsiniz (yaptığım şey bu)

33
Mark Fowler

Deneyin Perl 6 , beklentilerinizi daha kolay yerine getirdiği görülüyor:

===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
7
moritz