programowanieProgramista Perl / Główny programista ds. wsparcia projektów Perl

Wyjaśnij, jak działa zasięg leksykalny i dynamiczny w Perl, kiedy używane są my, local i our, oraz podaj przykłady problemów związanych z nieprawidłowym zrozumieniem tych różnic.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Perl zmienne mogą mieć leksykalny lub dynamiczny zasięg.

  • my tworzy zmienną z leksykalnym zasięgiem: zmienna jest widoczna tylko w bloku, w którym jest zdefiniowana.
  • local tymczasowo nadpisuje wartość globalnej (package) zmiennej z dynamicznym zasięgiem: nowa wartość jest widoczna we wszystkich wywołanych funkcjach do momentu wyjścia z bloku.
  • our definiuje globalną (package) zmienną, ale widoczną tylko w bieżącym bloku leksykalnym.

Przykład:

our $x = 10; sub test_my { my $x = 20; inner(); } sub test_loc { local $x = 30; inner(); } sub inner { print $x; } test_my(); # Wyświetli 10 — my $x nie jest widoczny w inner $| = 1; test_loc(); # Wyświetli 30 — local $x jest widoczny w inner

local jest używane do zmiany zmiennych pakietowych typu specjalne $_, $/, $@ itd.

Pytanie z podstępem

Jaki będzie wynik wykonania następującego kodu i dlaczego?

our $a = 5; sub outer { my $a = 10; inner(); } sub inner { print $a; } outer();

Odpowiedź: Wyświetli 5. Ponieważ zmienna my $a z outer nie jest widoczna w inner; używana jest zmienna pakietowa $a zadeklarowana przez our.

Przykłady rzeczywistych błędów z powodu nieznajomości niuansów tematu


Historia

W skrypcie analizy dzienników zalogowano statystyki do globalnego hasha za pomocą local, myśląc, że zmieniają wartość tylko wewnątrz bloku. Okazało się, że zmiana przez local rozprzestrzeniła się na inne części programu, co doprowadziło do utraty danych.

Historia

W testowaniu modułowym wielu deweloperów nadpisywało globalne zmienne specjalne typu $/ (separator linii) przez my, w wyniku czego zmiany nie zachodziły, a testy „padały” w dziwny sposób tylko częściowo.

Historia

W rozwoju JavaScript po przejściu na Perl deweloperzy z przyzwyczajenia starali się deklarować zmienne za pomocą our wszędzie tam, gdzie to nie było potrzebne, co prowadziło do powstawania nieoczekiwanych zmiennych globalnych, utrudniających enkapsulację i prowadzących do kolizji nazw.