Tine Perl rumit

Catatan Lane: Bertemu hari ini di Twitter sangat lucu, sekilas, utas. Dan kemudian dia melihat lebih dekat dan menyadari bahwa dia tidak hanya lucu, tetapi juga menghibur. Dan karena kebetulan hari ini adalah hari Jumat, saya memutuskan bahwa ada baiknya berbagi temuan dengan teman-teman saya :)

gambar

Simpan program berikut di /tmp/quine.pl

Illegal division by zero at /tmp/quine.pl line 1. 

Jalankan dengan perintah

 perl /tmp/quine.pl 

dan dia akan menampilkan kodenya sendiri.

"Trik-gempa" cukup sederhana untuk dikomposisikan dalam banyak bahasa pemrograman, di mana kesalahan sintaksis dalam sumber memprovokasi parser untuk menghasilkan kesalahan yang akan bertepatan dengan kode sumber program. Saya memposting beberapa trik ini di Twitter , termasuk yang berikut:

  File "quine.py", line 1 File "quine.py", line 1 ^ IndentationError: unexpected indent 

Tapi jelai mutiara di awal artikel ini adalah trik yang sama sekali berbeda - program ini mengerti dengan benar . Dan itu tidak bekerja lama, sampai tersandung pada kesalahan pembagian dengan nol. Quine ini sangat sensitif terhadap penamaan file - misalnya, menjalankan ./quine.pl tidak akan berfungsi.

Jadi pesan kesalahan ini sebenarnya seluruh program ?!

Program ini menggunakan banyak bar mutiara do-what-I-mean-parser.

Simbol / sangat tergantung pada konteks aplikasi dan dapat dianggap sebagai simbol pembagian, atau sebagai awal ekspresi reguler. Dan bahkan perubahan kecil dalam kode program ini menyebabkan kesalahan dalam menguraikan keteraturan, dan bukan untuk mengeksekusi kode. Dalam hal ini, kedua / karakter muncul dalam konteks operator.

Bagian non-kamus lain dari program ini adalah 1. , yang ditafsirkan hanya sebagai angka dan . yang merupakan operator gabungan.

Lalu apa arti kata-kata itu?

Kata-kata dalam Perl dapat berupa nama rutin, metode, paket, atau kelas. Atau (dalam mode malas) baris tanpa pemisah atau bahkan mungkin sesuatu yang saya lupa!

Perl juga menggunakan sintaks pemanggilan metode yang tidak biasa yang disebut " sintaks objek tidak langsung ", yang terlihat seperti ini:


paling sering Anda bisa melihat caranya

 print $filehandle "message"; my $instance = new Class(args); 

meskipun untuk Perl, sintaks berikut lebih disukai:

 $filehandle->print("message"); my $instance = Class->new(args); 

Dokumentasi perlobj mengatakan:

Perl menggunakan heuristik untuk mem-parsing kode ini, berdasarkan pada nama paket apa yang diketahuinya, subrutin apa yang ada dalam paket saat ini, kata-kata apa yang telah ditemui sebelumnya dan menganalisis data input lainnya. Tidak perlu dikatakan, heuristik dapat menghasilkan hasil yang sangat tak terduga!
Bagaimana dia menguraikan kode ini?
Mulai dari sisi kanan

 pl line 1. 

diuraikan sebagai pemanggilan metode

 line->pl(1.) 

di mana baris adalah nama paket (kelas), dan pl adalah metodenya.

Di tengah, "at", "tmp" dan "quine" diurai sebagai kata-kata sederhana, mis. string. Ekspresi diuraikan sebagai berikut:

 (("at" / "tmp") / "quine") . line->pl(1.) 

Di sebelah kiri adalah dua panggilan metode tidak langsung dilipat,

 division->Illegal(zero->by( ... )) 

Ekspresi internal yang dieksekusi pertama adalah:

 "at" / "tmp" 

Dan ini secara instan menyebabkan pembagian dengan pengecualian nol.

Source: https://habr.com/ru/post/id446958/


All Articles