programowanieProgramista Perl/Programista Backend

Jak działają konteksty w Perl (skalarny, listowy i void)? Podaj przykłady, kiedy wybór kontekstu wpływa na zachowanie kodu.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Perl są konteksty, które wpływają na działanie operatorów i funkcji:

  • Skalarny (scalar) — wyrażenie obliczane jest jako jedna wartość.
  • Listowy (list) — wyrażenie obliczane jest jako lista wartości.
  • Void — wynik nie jest używany.

Funkcje i operatory mogą zwracać różne wyniki w zależności od kontekstu.

Przykłady:

my @arr = (1, 2, 3); my $count = @arr; # kontekst skalarny: $count = 3 my @copy = @arr; # kontekst listowy: kopiuje całą tablicę my $line = <STDIN>; # odczytuje jedną linię (skalarny) my @lines = <STDIN>; # odczytuje wszystkie linie (listowy)

Kontekst można ustawić jawnie przez funkcję scalar():

my $last_idx = scalar @arr; # wymuszenie skalarny kontekst

Pytanie z podstępem

Jaką wartość zwróci funkcja keys %hash w kontekście skalarnym?

Odpowiedź: Zwróci liczbę elementów w hashu, a nie listę kluczy jak w kontekście listowym.

my %h = (a=>1, b=>2); my $num = keys %h; # $num = 2 my @keys = keys %h; # @keys = ('a', 'b')

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


Historia

W jednym projekcie zliczano liczbę elementów tablicy:

my @items = get_items(); my $cnt = @items;

Później ktoś postanowił przypisywać $cnt = get_items();, nie rozumiejąc, że funkcja zwraca listę — teraz zawsze otrzymywano tylko jedną (pierwszą) zwracaną wartość, a nie liczbę elementów.


Historia

Podczas czytania linii z pliku:

my $lines = <FILE>;

Spodziewając się otrzymać cały plik, uzyskano tylko pierwszą linię — nie uwzględniono, że w kontekście skalarnym zwracana jest jedyna linia.


Historia

Programista wywołał funkcję w kontekście void, nie używając uzyskaną wartość:

open_my_file(); # funkcja zwraca deskryptor, ale nie został zapisany

To skomplikowało debugowanie — funkcja działała, ale plik nigdzie nie był zapisywany, a błędy nie były łapane.