Saya sedang menjalankan ActiveState 32 bit ActivePerl 5.14.2 di Windows 7. Saya ingin main-main dengan hook pre-commit Git untuk mendeteksi program yang diperiksa dengan kesalahan sintaks. (Entah bagaimana saya hanya berhasil melakukan komit buruk.) Jadi sebagai program pengujian saya secara acak menuliskan ini:
use strict;
use warnings;
Syntax error!
exit 0;
Namun, itu mengkompilasi dan mengeksekusi tanpa peringatan, dan tingkat kesalahan adalah nol saat keluar. Bagaimana sintaksis yang valid ini?
no indirect
menghentikan hal-hal tersebut agar tidak terjadiwhatever / 25 ; # / ; die "this dies!";
Jawaban:
Perl memiliki sintaksis yang disebut "notasi metode tidak langsung". Itu memungkinkan
ditulis sebagai
Jadi itu berarti
sama dengan
atau
Tidak hanya sintaks yang valid, itu tidak menghasilkan kesalahan run-time karena hal pertama yang dilakukan adalah
exit(0)
.sumber
!exit(0)
tidak bisa lebih dari kesalahan ketik!$x
karena tidak ada yang diketik.new Class
danprint $fh ...
bukannyaClass->new(...)
dan$fh->print(...)
. Saya akan memberi Anda bahwa itu menyebabkan pesan kesalahan aneh, meskipunSaya tidak tahu mengapa, tapi inilah yang dibuat Perl:
Tampaknya pengurai mengira Anda memanggil metode
Syntax
pada-error
objek ... Aneh memang!sumber
exit(0)
dievaluasi terlebih dahulu, membuat program keluar sebelum mencoba meneruskan hasilnya'error'->Syntax()
.new Class
bukanClass->new()
. Untuk memanggil metodeSyntax
,exit
fungsi dijalankan, sehingga kesalahan run-time tidak pernah terjadi.use strict; use warnings; error->Syntax(! print "hi");
Hasil: Sintaks Ok pada perl -MO = Deparse juga, tetapi denganuse warnings
itu mungkin harus mengatakan sesuatu karena dapat mengetahui bahwa itu tidak dimuat. Alih-alih itu melempar kesalahan runtime "Tidak dapat menemukan metode objek ..".Alasan Anda tidak mendapatkan kesalahan adalah karena kode yang dieksekusi pertama kali adalah
Karena Anda tidak memiliki titik koma di baris pertama:
Compiler akan menebak (secara tidak benar) bahwa ini adalah panggilan subrutin dengan
not
operator!
dilemparkan. Ia kemudian akan menjalankan argumen untuk subrutin ini, yang kebetulan merupakanexit(0)
, di mana titik keluar program dan errorlevel set ke 0. Tidak ada lagi dijalankan , jadi tidak ada lagi kesalahan runtime yang dilaporkan.Anda akan melihat bahwa jika Anda mengubah
exit(0)
sesuatu sepertiprint "Hello world!"
Anda memang mendapatkan kesalahan:dan tingkat kesalahan Anda akan diatur:
sumber
>The compiler will guess (incorrectly)
Kompiler tidak dapat melakukan hal yang salah.Seperti disebutkan di atas ini disebabkan oleh notasi pemanggilan metode tidak langsung. Anda dapat memperingatkan ini:
Menghasilkan:
Ini membutuhkan modul CPAN tidak langsung .
Anda juga dapat menggunakan
no indirect "fatal";
untuk menyebabkan program mati (inilah yang saya lakukan)sumber
Coba Perl 6 , tampaknya memenuhi harapan Anda lebih mudah:
sumber
TLDR; Hampir tidak
sumber