W Perl proste struktury danych to scalary, tablice i hashe, do których odwołujemy się bezpośrednio po nazwie. Referencje (references) to scalary, które zawierają adresy innych struktur danych. Są niezbędne do tworzenia zagnieżdżonych (wielowymiarowych) tablic, zagnieżdżonych hashy i złożonych obiektów.
Przykład użycia referencji:
my %hash = ( foo => 1, bar => 2 ); my $ref = \%hash; print $ref->{foo}; # 1 # Tablica referencji do hashy my @array = ( { name => "Tom" }, { name => "Jerry" } ); print $array[1]{name}; # Jerry
Jeśli nie użyjesz referencji, nie będziesz w stanie stworzyć, na przykład, wielowymiarowej tablicy:
# Wielowymiarowa tablica przez referencje my $matrix = [ [1,2,3], [4,5,6] ]; print $matrix->[1][2]; # 6
Pozwala to na budowanie złożonych struktur danych, kompaktowe przekazywanie ich między funkcjami oraz wdrażanie wzorców OOP.
Czy można uzyskać dostęp do elementu zagnieżdżonej tablicy (lub hashy), nie używając referencji? Jeśli tak — jak, i kiedy to nie zadziała?
Często odpowiadają, że nie można, jednak w rzeczywistości Perl czasami "automatycznie" przekształca struktury. Ale bez referencji struktury zagnieżdżone nie będą działały, gdy są tworzone na bieżąco lub przekazywane jako argumenty.
Przykład nieprawidłowego i prawidłowego dostępu:
# Nie zadziała w ten sposób: my @arr = ( [1,2],[3,4] ); print $arr[0][1]; # 2 # Ale jeśli zadeklarujesz jako tablicę, a nie jako referencję, to: my @matrix = ( [1,2], [3,4] ); print $matrix[1][0]; # 3
Historia
W dużym projekcie próbując przekazać referencję do tablicy bez operatora \, wewnętrzna struktura "rozkładała się" jako tablica skalarów, co prowadziło do całkowitego naruszenia logiki.
Historia
Programista pomieszał odwołania przez referencje i bez referencji w kodzie, w wyniku czego część danych ginęła w zagnieżdżonych pętlach foreach podczas pracy z tablicą referencji.
Historia
Podczas pracy z konfiguracją, zagnieżdżoną przez hash referencji, zapomniano zdereferencjonować referencję i próbowano uzyskać dostęp do niej jak do hasha, co powodowało błąd wykonania "Can't use string ("HASH(0x1234)") as a HASH" w produkcji.