Neden katı ve uyarılar kullanıyorsunuz?


104

Bana öyle geliyor ki Perl etiketindeki soruların çoğu, eğer insanlar şunları kullanırsa çözülebilir:

use strict;
use warnings;

Bence bazı insanlar bunların eğitim tekerlekleri veya gereksiz komplikasyonlara benzediğini düşünüyorlar ki bu kesinlikle doğru değil çünkü çok yetenekli Perl programcıları bile kullanıyor.

Görünüşe göre Perl'de yetkin olan çoğu insan bu iki pragmayı her zaman kullanıyor, oysa bunları kullanmaktan en çok fayda sağlayacak olanlar nadiren kullanıyor. Yani, bundan insanları teşvik ederken ve bağlantıya bir sorum var için iyi bir fikir olacağını düşündük use strictve warnings.

Öyleyse, neden bir Perl geliştiricisi use strictve warnings?


14
Hep böyle şeyleri merak ediyorum, neden sadece varsayılan yapmıyorlar ve geliştiricinin işleri aktif olarak gevşetmesi gerekiyor, neredeuse loose;
Paul Tyng

12
Birçok harika ve faydalı şey gibi, Perl de onu icat eden adam için bir araç olarak, bir hack olarak başladı. Daha sonra daha popüler hale geldi ve artan sayıda vasıfsız insan kullanmaya başladı. Bu, use strictiyi bir fikirmiş gibi düşünmeye başladığınız zamandır , ancak geriye dönük uyumluluk sizin için zaten gerçek bir sorun haline geldi :-(
Daniel Böhmer

14
@JB Nizet, @Paul T., Aslında, use strict;Perl 5.12 (veya daha yüksek) dilini talep ettiğinizde varsayılan olarak açıktır. Deneyin perl -e"use v5.012; $x=123;". no strict;aslında onu kapatır.
ikegami

1
Sonunda amacınız doğru olsa da, ne kadar çok söylersek, belki o kadar çok insan duyacaktır. Son zamanlarda daha fazla / daha iyi / modern Perl öğreticilerini kullanıma sunmaya çalışırken bazı gürlemeler oldu ve kesinlikle bunların her birinin üstünde katı / uyarılar olacak. Benimki için, her pasajın üstünde s / w olmasını planlıyorum, böylece tüm yeni başlayanlar her seferinde görsün
Joel Berger

5
@JoelBerger Hayır, aslında hiç de öyle değil. Dediğim gibi, sadece başlıkta benzer kelimeler var. Geriye dönük uyumluluk içindir. Kabul edilen cevaptaki ilk cümle, bunun soruma uygulanmasını nasıl öneriyorsunuz?
TLP

Yanıtlar:


83

Yeni başlayanlar için use strict;(ve daha az ölçüde use warnings;) değişken adlarındaki yazım hatalarını bulmaya yardımcı olur. Deneyimli programcılar bile böyle hatalar yapar. Yaygın bir durum, kodu temizlerken veya yeniden düzenlerken bir değişken örneğini yeniden adlandırmayı unutmaktır.

Kullanmak use strict; use warnings;birçok hatayı başka türlü yakalanacaklarından daha erken yakalar, bu da hataların temel nedenlerini bulmayı kolaylaştırır. Temel neden, bir hata veya doğrulama kontrolü ihtiyacı olabilir ve bu, programcı becerisine veya becerisine bakılmaksızın gerçekleşebilir.

Perl uyarılarının iyi yanı, nadiren sahte olmalarıdır, bu nedenle bunları kullanmanın neredeyse hiçbir maliyeti yoktur.


İlgili okuma: Neden kullanmalı my?


2
@TLP, ne kadar yardımcı olduğunu ölçmek için bir çalışma yapmak üzere değilim. Kayıtsız şartsız yardım ettiklerini söylemek yeterli olacaktır.
ikegami

1
O kadar çok faydası varsa, neden isteğe bağlı hale getirildi? Neden varsayılan olarak etkinleştirmiyorsunuz (yukarıda yorum yapılan biri gibi)? Uyumluluk nedeniyle mi?
Jean

4
@ Jean, geriye dönük uyumluluk. use strict;5.12 veya dilin ( use 5.012;) daha yenisini kullanıyorsanız varsayılan olarak etkinleştirildiğini unutmayın .
ikegami

@Jean Eğer basit bir betik yazıyorsanız, dosya işleyici isimleriyle ilgili uyarılarla veya değişkeni kullanmadan önce bildirmediğiniz için uyarı almak istemezsiniz :-)
user2676847

28

Görünüşe göre use strictperl'i düzgün bir şekilde kodlamaya zorlamak istediğinizde kullanılmalı (zorunludur), bu da bildirimi zorlayabilir, dizeler ve alt sözcükler üzerinde açık olabilir, yani barewords veya referansları dikkatli kullanarak. Not: Hatalar varsa, sıkı kullan kullanılırsa yürütmeyi durdurur.

use warnings;Bir noktalı virgülü kaçırmışsınız gibi programdaki yazım hatalarını bulmanıza yardımcı olacak olsa da, 'elsif' değil 'elseif' kullandınız, bunun gibi kullanımdan kaldırılmış sözdizimi veya işlevi kullanıyorsunuz. Not: Kullanım uyarıları yalnızca uyarılar sağlar ve yürütmeye devam eder, yani yürütmeyi iptal etmez ..

Her neyse, aşağıda belirttiğim ayrıntılara girersek daha iyi olur.

Gönderen perl.com (en sevdiğim):

katı 'değişkenler' kullanın;

bu, değişkenleri kullanmadan önce her zaman bildirmeniz gerektiği anlamına gelir.

Bildirmezseniz, muhtemelen bildirilmemiş değişken için hata mesajı alırsınız.

"$ Variablename" global sembolü, scriptname.pl 3. satırda açık paket adı gerektiriyor

Bu uyarı Perl'in değişkenin kapsamının ne olduğu konusunda tam olarak net olmadığı anlamına gelir. Bu yüzden değişkenleriniz hakkında açık olmanız gerekir, yani onları mymevcut blokla sınırlı olarak bildirmek veya onlara tam olarak nitelenmiş isimleriyle atıfta bulunmak (örneğin: $ MAIN :: variablename).

Bu nedenle, aşağıdaki kriterlerden en az birini karşılamayan bir değişkene erişmeye çalışırsanız bir derleme zamanı hatası tetiklenir:

  • @ARGV,% ENV ve $ gibi tüm genel noktalama değişkenleri gibi Perl'in kendisi tarafından önceden tanımlanmıştır. veya $ _.

  • Bizim (global için) veya benim (sözlük için) ile ilan edildi.

  • Başka bir paketten içe aktarıldı. (Vars pragma kullanımı bir içe aktarmayı taklit eder, ancak onun yerine bizimkini kullanın.)

  • Paket adını ve çift iki nokta üst üste paket ayırıcısını kullanarak tam nitelikli.

sıkı 'alt' kullanın;

İki program düşünün

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

Her iki durumda da bir test_value () subumuz var ve sonucunu $ a'ya koymak istiyoruz. Yine de, iki programı çalıştırdığımızda iki farklı sonuç elde ederiz:

İlk programda, geldiğimiz noktada $a = test_value;Perl herhangi bir test_value () altını bilmiyor ve test_value 'test_value' dizesi olarak yorumlanıyor. İkinci programda test_value () tanımı $a = test_value;satırdan önce gelir . Perl, test_value'yu alt çağrı olarak düşünür.

Bu arada, alt ve bağlama bağlı olarak dizeler olabilecek test_value gibi yalıtılmış sözcükler için teknik terim açık bir sözcüktür . Perl'in barewords kullanımı kafa karıştırıcı olabilir ve programda hataya neden olabilir.

Hata, ilk programımızda karşılaştığımız şeydir, Perl'in bulmayı dört gözle test_value()beklemeyeceğini unutmayın, bu nedenle test_value () 'u daha önce görmediğinden, bir dizge istediğinizi varsayar. Yani eğer sen use strict subs;, bu programın bir hata ile ölmesine sebep olur:

./A6-strictsubs.pl 3. satırda "sıkı alt" kullanımdayken bareword "test_value" kullanımına izin verilmez.

Bu hatanın çözümü
1 olacaktır . Bir aboneyi aradığınızı açıkça belirtmek için parantez kullanın. Perl $ a = test_value (); görürse,
2. Aboneliğinizi ilk kullanmadan önce bildirin

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. Ve onu bir dizge olarak kullanmak istiyorsan, alıntı yap.

Bu nedenle, bu kısıtlama Perl'in tüm çıplak sözcükleri sözdizimi hataları olarak değerlendirmesine neden olur. * Bir engel , bağlam tarafından zorlanan başka bir yorumu olmayan herhangi bir çıplak isim veya tanımlayıcıdır. (Bağlam, genellikle yakındaki bir anahtar kelime veya simge tarafından veya söz konusu kelimenin önceden bildirilmesiyle zorlanır.) * Dolayısıyla, onu bir dizge olarak kullanmak istiyorsanız, alıntı yapın ve bir işlev çağrısı olarak kullanmak istiyorsanız, önceden beyan edin. veya parantez kullanın.

Barewords, bu öngörülemeyen davranış nedeniyle tehlikelidir. use strict; (or use strict 'subs';)onları öngörülebilir kılar, çünkü gelecekte tuhaf davranışlara neden olabilecek yalancı sözler, programınızı hasara yol açmadan önce ölür.

Katı aboneleri açmış olsanız bile, barewords kullanmanın uygun olduğu bir yer var: hash anahtarları atarken.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

Hash anahtarlarındaki barewords her zaman dizeler olarak yorumlanır, bu nedenle belirsizlik yoktur.

katı 'referanslar' kullanın;

Bu, kasıtlı olarak veya başka bir şekilde sembolik referanslar kullanırsanız bir çalışma zamanı hatası oluşturur. Sabit bir referans olmayan bir değer daha sonra sembolik bir referans olarak kabul edilir . Yani başvuru, global bir değişkenin adını temsil eden bir dizge olarak yorumlanır.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

uyarıları kullanın;

Bu sözcüksel kapsamlı pragma, hem derleyici tarafından hem de çalışma zamanı sisteminden gönderilenler olmak üzere Perl'in yerleşik uyarıları üzerinde esnek kontrole izin verir.

Kimden perldiag:

Bu nedenle, aşağıdaki sınıflandırmalardaki uyarı mesajlarının çoğu, yani W, D ve S, warningspragma kullanılarak kontrol edilebilir .

(W) Bir uyarı (isteğe bağlı)
(D) Bir kullanımdan kaldırma (varsayılan olarak etkindir)
(S) Ciddi bir uyarı (varsayılan olarak etkindir)

Aşağıda sıklıkla görülen uyarı mesajlarından bazılarını sınıflandırmalara göre listeledim. Onlar ve diğer mesajlar hakkında ayrıntılı bilgi için perldiag'a bakın

(W) Bir uyarı (isteğe bağlı):

% S içinde
eksik bağımsız değişken -% c için bağımsız değişken eksik
(Onun yerine &% s mi demek istediniz?)
("Bizim" yerine "yerel" mi demek istediniz?)
(% Yerine $ mı yoksa @ mi demek istediniz?)
'% S ', numarada
% s
Yanlış yerleştirilmiş _ üzerinde kullanılan bir kod referans uzunluğu () değil

(D) Kullanımdan kaldırma (varsayılan olarak etkindir):

tanımlı (@array) kullanımdan kaldırıldı
tanımlandı (% hash) kullanımdan kaldırıldı
my () 'ın yanlış koşullu
$ # içinde kullanımı artık desteklenmiyor

(S) Ciddi bir uyarı (varsayılan olarak etkindir)

elseif,
operatörün beklediği yerde elsif % s bulunmalıdır
(% s'den önce operatör eksik?)
(Önceki satırda noktalı virgül eksik mi?)
% s hiç tanıtılmamış
Operatör veya% s öncesinde noktalı virgül eksik
Öncelik sorunu: open% s açık olmalı (% s)
Prototip uyuşmazlığı:% s -% s
Uyarı: Parantez olmadan "% s" kullanımı belirsizdir
% s açılamıyor:% s


10

Bu iki pragma, kodunuzdaki hataları otomatik olarak tanımlayabilir.

Bunu her zaman kodumda kullanırım:

use strict;
use warnings FATAL => 'all';

FATALtıpkı strictyaptığı gibi, kodun uyarılarda ölmesini sağlar .

Daha fazla bilgi için, bkz: Kullanım uyarılarıyla daha katı olun FATAL => 'all';

Ayrıca ... Seuss'a göre kısıtlamalar


Aslında, FATAL => "all"çalışma zamanını atayarak ertelemelisiniz, $SIG{__WARN__} = sub { croak "fatalized warning @_" };yoksa derleyiciyi size neye ihtiyacı olduğunu söylemeye çalışırken batırırsınız.
tchrist

6
@tchrist: Bu benim için her zaman olduğu gibi ve belgelendiği gibi çalıştı. Belgelendiği gibi çalışmayan bir vaka bulduysanız, lütfen kullanarak belgelere yama yapın perlbug.
toolic


3

Kaynak :: Farklı bloglar

Kullanım, modüller import () işlevini çağırarak işlevleri ve değişken adlarını ana ad alanına dışa aktaracaktır.

Pragma, perl.Pragmalar'ın derleme zamanının veya çalışma zamanı davranışının bazı yönlerini etkileyen bir modüldür.

Uyarıları kullanın - yalnızca bir kez kullanılan değişkenlerle ilgili perl şikayetleri, dizelerin sayılara uygun olmayan şekilde dönüştürülmesi, Açılmayan dosyalara yazmaya çalışılması, derleme zamanında gerçekleşir. Uyarıları kontrol etmek için kullanılır.

Katı - değişkenler kapsamını bildir. Senaryoda bir tür disiplini ayarlamak için kullanılır.Kodda barewords kullanılmışsa yorumlanırlar. My, our veya local gibi tüm değişkenlere kapsam verilmelidir.


1

"Use tight" yönergesi Perl'e kodunuzun derlenmesi sırasında fazladan kontrol yapmasını söyler. Bu yönergeyi kullanmak, Perl kodunuzda hata ayıklama konusunda size zaman kazandıracaktır çünkü aksi takdirde gözden kaçırabileceğiniz yaygın kodlama hatalarını bulur.


0

Katı ve uyarılar, değişkenlerinizin genel olmadığından emin olun.

Her bir değişken adının kaydını tutmak yerine, bireysel yöntemlere özgü değişkenlere sahip olmak çok daha derli topludur.

$ _ veya belirli işlevler için değişken olmaması, daha kompakt kodu daha hızlı yazmak için de yararlı olabilir.

Ancak, katı ve uyarılar kullanmazsanız, $ _ global olur!


0
use strict;
use warnings;

Katı ve uyarılar, perl programının modudur. Kullanıcının kodu daha özgürce ve bundan daha fazla girmesine izin verir, bu perl kodu resmi görünecek ve kodlama standardı etkili olacaktır.

uyarılar -w, perl shebang satırında olduğu gibi aynı anlama gelir , bu nedenle size perl programı tarafından oluşturulan uyarıları sağlar, terminalde görüntülenir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.