ProgramlamaBackend Geliştirici

Perl'de sözdizimsel ve paket değişkenleri nasıl çalışır: my, our ve state arasındaki farklar nelerdir, bunlar ne zaman doğru kullanılmalıdır ve pratikte hangi hatalarla karşılaşılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Perl'de değişkenleri tanımlamak için üç ana tür vardır: my, our ve state.

  • my bir blok içinde (sözdizimsel kapsam) görünürlüğü olan sözdizimsel bir değişken oluşturur.
  • our bir pakette küresel olarak erişilebilen, fakat yalnızca sözdizimsel blok içinde görülebilen paket değişkeni oluşturur. Modüller arasında ad alanlarını düzenlemek için faydalıdır.
  • state Perl 5.10'dan itibaren eklenmiştir ve bir alt program çağrıları arasında değerini koruyan sözdizimsel bir değişken oluşturur (temelde statik bir değişken).
sub example_state { state $counter = 0; $counter++; return $counter; } for (1..3) { print example_state(), " "; # 1, ardından 2, ardından 3 yazdırır }

Doğru kullanımı:

  • my — değişkenler için neredeyse her zaman tercih edilen seçimdir, küresel erişim gerektirmediği sürece.
  • our — bir modül arasında değişkenleri dışa aktarmak için, paylaşıma ihtiyaç duyulduğunda.
  • state — bir değişkenin fonksiyon çağrıları arasında değerini "hatırlaması" gerektiğinde (örneğin, çağrı sayacı).

Yanıltıcı soru

our ile tanımlanan bir değişken, my ile birlikte bir kapalı (closure) içinde kapatılabilir mi?

Genellikle “evet, bu kullanışlı” diye yanıtlanır, ancak durum böyle değildir. our değişkeni, paket için küreseldir ve kapalı (closure) temel olarak onu ortaya çıkma anında değeriyle bağlamaktan ziyade küresel isim üzerinden erişimi gerçekleştirir. Bu nedenle, onun "değeri" kapalı (closure) dışından değiştirilebilir ve tüm kapalı (closure) yapıları etkileyebilir!

our $x = 10; my $closure = sub { return $x; }; $x = 42; print $closure->(); # 10 yerine 42 döner

Bilgi eksikliklerinden kaynaklanan gerçek hata örnekleri


Hikaye

Büyük bir günlük ayrıştırma scriptinde, değişkenler farklı modül fonksiyonlarından "rahat erişim" sağlamak için our ile tanımlanıyordu. Sonuç olarak, bu değişkenlerin bir fonksiyondaki değişiklikleri diğerinde beklenmedik davranışlara yol açarak günlüklerin paralel işlenmesini bozuyordu.


Hikaye

Fonksiyon çağrıları arasında değerlerinin korunması gereken değişkenler için my kullanımı (örneğin, özyinelemeli geçişte sayaç) her çağrıda değerin sıfırlanmasına neden olarak geçiş mantığında hatalara yol açıyordu. state ile değiştirmek durumu düzeltmişti.


Hikaye

İçeri aktarılan bir modülde our'ın yanlış kullanımı (değişkenleri Exporter aracılığıyla dışa aktarmamak) iki farklı modülün aynı değişken adını kullanması nedeniyle ad çakışmasına yol açtı. Sonuç olarak, veriler bir bağlamdan diğerine "atladı".