Kullanım
"diagnostics" pragmasının kullanımı:
use diagnostics;
use diagnostics -verbose;
enable diagnostics;
disable diagnostics;
Tek başına çalışan "splain" filtre programının kullanımı:
perl program 2>diag.out
splain [-v] [-p] diag.out
Hatalı çalışan bir betikten yığın izlerini (stack trace) almak için diagnostics kullanımı:
perl -Mdiagnostics=-traceonly my_script.pl
Açıklama
"diagnostics" Pragması Bu modül, hem perl derleyicisi hem de perl yorumlayıcısı tarafından normalde üretilen (perl'ün -w anahtarı veya "use warnings" ile çalıştırılmasından kaynaklanan) kısa teşhisleri genişletir ve bunları perldiag içinde bulunan daha açıklayıcı ve sevimli açıklamalarla zenginleştirir. Diğer pragmalar gibi, programınızın yalnızca yürütme aşamasından ziyade derleme aşamasını etkiler.
Programınızda bir pragma olarak kullanmak için, programınızın başında (veya başına yakın bir yerinde) sadece
use diagnostics;
ifadesini çağırmanız yeterlidir. (Bunun perl'ün -w bayrağını etkinleştirdiğini unutmayın.) Böylece tüm derlemeniz gelişmiş teşhislere tabi tutulacaktır (tabi olacaktır :-)). Bunlar yine de STDERR'e (standart hata çıktısı) gönderilir.
Çalışma zamanı ve derleme zamanı sorunları arasındaki etkileşim nedeniyle ve zaten muhtemelen çok iyi bir fikir olmadığından, bunları derleme zamanında kapatmak için "no diagnostics" ifadesini kullanamazsınız. Ancak, sırasıyla kapatmak ve açmak için disable() ve enable() metotlarını kullanarak çalışma zamanındaki davranışlarını kontrol edebilirsiniz.
-verbose bayrağı, diğer herhangi bir teşhisten önce ilk olarak perldiag girişini yazdırır. $diagnostics::PRETTY değişkeni, sayfalayıcılar (pager) için daha hoş kaçış dizileri (escape sequences) üretebilir.
Perl'ün kendisinden gönderilen uyarılar (veya daha doğru bir ifadeyle, perldiag içinde bulunan açıklamalara uyanlar) yalnızca bir kez görüntülenir (yinelenen açıklamalar olmaz). Kullanıcı kodunun warn() benzeri ürettiği uyarılar bundan etkilenmez, böylece yinelenen kullanıcı mesajlarının görüntülenmesine izin verilir.
Bu modül ayrıca perl sonlandığında (die) hata mesajına bir yığın izi (stack trace) ekler. Bu, sonlanmaya neyin sebep olduğunu tam olarak belirlemek için kullanışlıdır. -traceonly (veya sadece -t) bayrağı, uyarı mesajlarının açıklamalarını kapatarak geriye yalnızca yığın izlerini bırakır. Dolayısıyla, betiğiniz sonlanıyorsa, betiği tekrar şu şekilde çalıştırın:
perl -Mdiagnostics=-traceonly my_bad_script
sonlanma anındaki çağrı yığınını görmek için. -warntrace (veya sadece -w) bayrağını sağlayarak, yayılan tüm uyarıların da bir yığın iziyle birlikte gelmesini sağlayabilirsiniz.
splain Programı Görünüşe göre tamamen başka bir program olsa da splain aslında (yürütülebilir) diagnostics.pm modülüne bir bağlantı olmanın yanı sıra diagnostics.pod dokümantasyonuna da bir bağlantıdan başka bir şey değildir. -v bayrağı "use diagnostics -verbose" yönergesine benzer. -p bayrağı ise $diagnostics::PRETTY değişkenine benzer. splain ile sonradan işleme (post-processing) yaptığınız için, işlemi enable() veya disable() edebilmenin bir anlamı yoktur.
Pragmadan farklı olarak, splain çıktısı STDOUT'a (standart çıktı) yönlendirilir.
Örnekler
Aşağıdaki dosyanın hem çalışma zamanında hem de derleme zamanında birkaç hatayı tetikleyeceği kesindir:
use diagnostics;
print NOWHERE "nothing\n";
print STDERR "\n\tThis message should be unadorned.\n";
warn "\tThis is a user warning";
print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: ";
my $a, $b = scalar <STDIN>;
print "\n";
print $x/$y;
Öncelikle programınızı çalıştırmayı ve sorunlarına daha sonra bakmayı tercih ediyorsanız, şunu yapın:
perl -w test.pl 2>test.out
./splain < test.out
Bunun, daha şüpheli kökenlere sahip kabuklarda (shell) genel olarak mümkün olmadığını unutmayın, çünkü teorik olarak
(perl -w test.pl >/dev/tty) >& test.out
./splain < test.out
çalışmayacaktır, çünkü mevcut stdout'u başka bir yere taşımış oldunuz.
Kaynak kodunuzu değiştirmek istemiyor ancak yine de anında (on-the-fly) uyarılar almak istiyorsanız, şunu yapın:
exec 3>&1; perl -w test.pl 2>&1 1>&3 3>&- | splain 1>&2 3>&-
Şık, değil mi?
Uyarıları anında kontrol etmek istiyorsanız, şunun gibi bir şey yapın. Önce "use" işlemini yaptığınızdan emin olun, aksi takdirde enable() veya disable() metotlarına erişemezsiniz.
use diagnostics; # tüm derleme aşamasını kontrol eder
print "\ntime for 1st bogus diags: SQUAWKINGS\n";
print BOGUS1 'nada';
print "done with 1st bogus\n";
disable diagnostics; # yalnızca çalışma zamanı uyarılarını kapatır
print "\ntime for 2nd bogus: (squelched)\n";
print BOGUS2 'nada';
print "done with 2nd bogus\n";
enable diagnostics; # çalışma zamanı uyarılarını tekrar açar
print "\ntime for 3rd bogus: SQUAWKINGS\n";
print BOGUS3 'nada';
print "done with 3rd bogus\n";
disable diagnostics;
print "\ntime for 4th bogus: (squelched)\n";
print BOGUS4 'nada';
print "done with 4th bogus\n";
İç Yapı
Teşhis mesajları, çalışma zamanında mevcut olduğunda perldiag.pod dosyasından alınır. Aksi takdirde, splain paketi derlendiğinde dosyanın kendisine gömülebilirler. Detaylar için Makefile dosyasına bakın.
Eğer mevcut bir $SIG{WARN} yakalayıcısı (handler) tespit edilirse, buna uyulmaya devam edilecektir; ancak bu yalnızca diagnostics::splainthis() işlevi (modülün $SIG{WARN} kesicisi) uyarılarınızı kendi yöntemiyle işledikten sonra gerçekleşir.
Ne tür şeylerin kesildiğini can havliyle merak ediyorsanız ayarlayabileceğiniz bir $diagnostics::DEBUG değişkeni vardır.
BEGIN { $diagnostics::DEBUG = 1 }
Hatalar
"no diagnostics" diyememek can sıkıcıdır, ancak aşılamaz olmayabilir.
"-pretty" yönergesi, durumu etkilemek için çok geç çağrılır. Bunun yerine ve modülü yüklemeden önce şunu yapmanız gerekir.
BEGIN { $diagnostics::PRETTY = 1 }
Derlemeyi ihtiyaç duyulana kadar erteleyerek daha hızlı başlayabilirdim, ancak bu durum Perl 5.001e'de pragma formu kullanılırken "panic: top_level" hatasına yol açıyor.
Bu dokümantasyonun biraz gayriciddi olduğu doğru olsa da, splain adında bir program kullanıyorsanız biraz tuhaflık beklemelisiniz.
Yazar
Tom Christiansen tchrist@mox.perl.com, 25 Haziran 1995.