Odkazy

Rozlišují se dva základní typy odkazů - symbolické odkazy a pevné odkazy.

Pevné odkazy

Pevný odkaz (reference)je hodnota, která obsahuje konkrétní adresu v paměti, kde se nachází odkazovaná hodnota. Získání hodnoty z odkazu se nazývá dereference, Odkazy mohou odkazovat na různé typy objektů. Podle toho se rozlišují odkazy na skalár, pole, hash, podprogram a typeglob. Typ odkazu lze získat jako návratovou hodnotu funkce ref, jejíž návratové hodnoty jsou REF (odkaz), SCALAR (odkaz na skalár), ARRAY (odkaz na pole), HASH (odkaz na hash), CODE (odkaz na prodprogram), GLOB (odkaz na typeglob) a pak případně jméno objektové třídy.

Perl umožňnuje vytvářet jak odkazy na existující proměnné, tak odkazy na nepojmenované datové struktury (anonynmí), vytvářet odkazy staticky i dynamicky (tzn. v průběhu provádění programu).

Při pokusu použít proměnnou, která je odkazem, způsobem, jako by odkazem nebyla, se neprovádí implicitní dereference, ale Perl se snaží nějakým způsobem odkaz interpretovat tak, aby nevznikla chyba. V případě, že to nelze, ukončí se program s chybou. Tento problém vzniká například při volání vestavěných funkcí, kde je očekávány konkrétní typy argumentů.

$x = 123;   # nastavení hodnoty proměnné
$rx = \$x;  # vytvoření odkazu na proměnnou

print $rx;  # pokus tisnout odkaz
            # vytiskne se SCALAR(0x1ac2b14)

%h = (1 => 'a');   # vytvoření hashe
$rh = \%h;         # vytvoření odkazu na hash
print keys $rh;    # chyba - očekáván hash

Vytváření pevných odkazů

Existuje několik způsobů vytváření pevných odkazů. Výsledek nezávisí na použitém způsobu vytváření odkazů a práce s takovýmito odkazy a jejich dereference je stejné. Chceme-li zjistit, zda dvě proměnné odkazují na stejnou hodnotu, jednoduše je lze porovnat.

Operátor obrácené lomítko

Tento operátor se používá pro získání odkazu na proměnnou, podprogram nebo skalární hodnotu (není možné vytvořit odkaz na ovladač, jedinou možností je využit odkazu na typeglob).
$scalar_reference = \$prom;
$array_reference = \@pole;
$hash_reference = \%hash;
$code_reference = \&podprogram;  # nutnost použití &
$glob_reference = \*TYPEGLOB;
$const_reference = \123;

Uvedeme-li operátor zpětné lomítko před seznamem hodnot, dochází k tomu, že výsledkem bude seznam odkazů na původní hodnoty.

@seznam_odkazu = \($s, @p, %h, &f);
@seznam_odkazu = (\$s, \@p, \%h, \&f);       # to stejné
V případě, že seznam obsahuje pouze jedno pole nebo hash, dojde k tomu, že operátor zpětné lomítko se doplní před každý prvek tohoto seznamu a je vrácen seznam odkazů na hodnoty původního seznamu. Použijeme-li tento zápis na hash, budou vráceny odkazy na hodnoty hashe a odkazy na kopie klíčů hashe (nikoliv odkazy na klíče).
@seznam_odkazu = \(@pole);
@seznam_odkazu = map {\$_} @pole;                 # to stejné
(\$a, \$b, map {\$_} @pole);     # to stejné
Použijeme-li operátor zpětné lomítko před voláním funkce, získáme seznam odkazů na jednotlivé hodnoty vrácené danou funkcí.
@seznam_odkazu = \funkce();
@seznam_odkazu = map {\$_} funkce();   # to stejné

Konstruktor anonymního pole

Anonymní pole je pole, které není nijak pojmenováno (narozdíl od předchozího příkladu, kdy se pole jmenovalo @pole). Pro vytvoření odkazu na takovéto pole se použije operátoru hranatých závorek.
$array_reference = [1, 'a', 'xxxxx'];
V případě použití konstruktoru anonymního pole je vytvořena nová datová struktura.

Konstruktor anonymního hashe

K vytvoření odkazu na anonymní hash se použije operátoru složených závorek.
$dny_ref = { 'Pondělí' => 1,
	     'Úterý' => 2,
	     'Středa' => 3,
	     'Čtvrtek' => 4,
	     'Pátek' => 5};
Pravidla pro hodnoty hashového literálu jsou stejné jako u běžného hashe -- jako klíče musejí být použity řetězcové literály nebo proměnné a výrazy.

Složené závorky mají ještě některá další použití, proto je třeba odlišit případ, kdy mají sloužit jako konstruktor anonymního hashe. Například ve funkci, která vrací odkaz na hash, jehož klíče a hodnoty budou zadány jako seznam argumentů této funkce, je třeba použít operátor unární + nebo funkci return.

sub hash_reference { +{ @_ } }          # správně
sub hash_reference { return { @_ } }    # správně
sub hash_reference { { @_} }            # špatně v tomto případě jsou vnitřní
                                        # složené závorky považovány za začátek bloku
V případě, že chceme, aby složené závorky byly považovány za začátek bloku, můžeme to zdůraznit následovně.
	sub func { { ; @_} }
	sub func { { return @_ } }

Konstruktor anonymního podprogramu

Odkaz na anonymní podprogram se vytvoří použitím operátoru sub bez jména podprogramu. Za složenými závorkami uzavírajícími tělo podprogramu musí být nutně uveden středník.
$code_reference = sub { print "Ahoj." };

Konstruktory objektů

Existují speciální podprogramy zvané konstruktory, které vracejí odkaz na objekt. Objekty v Perlu jsou odkazy na nějaký obsah proměnné, který ví, ke které třídě náleží (blíže v kapitole o objektech). Konstruktory umí tuto asociaci obsahu proměnné s třídou provést (využívá se operátoru bless). Konstruktory se zpravidla pojmenovávají new, ale není to nutnost. Objekt je vytvořen například následujícím způsobem.
$object = new Class;

Vytváření odkazů pomocí syntaxe *jmeno{TYP}

Pomocí této syntaxe získáme odkaz na položku pro datový typ TYP v tabulce symbolů na pozici jmeno.
$scalar_reference = *aaa{SCALAR}
$array_reference = *aaa{ARRAY}
$hash_reference = *aaa{HASH}
$code_reference = *aaa{CODE}
$handle_reference = *AAA{IO}  # nebo *AAA{FILEHANDLE}
$glob_reference = *aaa{GLOB}
V proměnné \$scalar_reference bude odkaz na proměnnou \$aaa atd.

Výraz s touto syntaxí vrací nedefinovanou hodnotu v případě, že neexistuje struktura, na niž chceme získat odkaz. V našem případě by například výraz \$hash_reference = *aaa{HASH} vracel nedefinovanou hodnotu, jestliže by hash se jménem %aaa zatím nikde nebyl použit. Výjimkou je použití tohoto výrazu na neexistující skalární proměnnou -- tato proměnná potom začne automaticky existovat.

Implicitní vytváření odkazů

V podstatě se žádný odkaz nevytváří, začnou existovat v případě, že se provádí dereference v tom kontextu, který předpokládá, že tento odkaz existuje.

Používání pevných odkazů

Podobně jako při vytváření odkazů existuje několik metod jak odkazy dereferencovat. Tam, kde by se mohl ve jménu proměnné nebo podprogramu použít alfanumerický řetězec, je možné umístit skalární proměnnou obsahující odkaz správného typu (obsahuje-li proměnná $pole odkaz na pole, použijeme tuto proměnnou všude tam, kde bychom jinak použili jméno pole, na které se odkazujeme).

Příklady dereferencí:

$hodnota = $$scalar_reference;
push @$array_reference, $retezec;
$$array_reference[0] = 12345;
$$hash_reference{"KLÍČ"} = "HODNOTA";
&$code_reference (1, 2, 3);  # další případ, kdy je nutné před
                             # jménem podporgramu psát znak &
print *glob_reference "výstupní hodnota\n";
Jednoduché skaláry mohou tuto metodu dereference použít rekurzivně.
$refrefref = \\\"text\n";
print $$$$refrefref;	# vytiskne "text"
Z kapitoly o prioritě operátorů víme, že dereference se provádí v každém výrazu na druhém místě -- má tedy značnou prioritu (vyšší prioritu má jen term). Je třeba uvědomit si, že nedereferencujeme výraz $array_reference[0] nebo $hash_reference{"KLÍČ"}, ale že k dereferenci dochází ještě před jakýmkoliv hledáním v poli nebo hashi. Cokoliv, co je složitější než jednoduchý skalár musí používat některou z metod dereference uvedenou dále.

Stejně, jako jsme ve jméně proměnné použili proměnnou, která je odkazem, můžeme použít blok, který vrací odkaz (blok je výraz uzavřený do dvojice složených závorek).

$prom = ${$scalar_reference};
push @{$array_reference}, $retezec;
${$array_reference}[0] = 12345;
${$hashref}{"KEY"} = "VALUE";
&{$code_reference}(1, 2, 3);  # další případ, kdy je nutné
                              # před jménem podporgramu psát znak &
Tento zápis je nezbytný v případě, že chceme použít odkaz jako součást jména proměnné a tento odkaz není jen jednoduchá skalární proměnná, ale složitější výraz. V případě, že chceme pracovat s prvkem pole nebo hodnotou hashe, nebo chceme volat funkci, na kterou je vytvořena reference, můžeme použít zápis pomocí operátoru ->. Tento operátor provede dereferenci výrazu na levé straně a potom se tímto výrazem pracuje jako s typem, na který se odkazujeme.
$array_reference = \@pole;
$array_reference->[0];      # je první prvek pole @pole
                            # to stejné, co $$array_reference[0]
$hash_reference = \%hash;
$hash_reference->{KLÍČ}     # je hodnota hashe %hash na pozici KLÍČ
                            # to stejné, co $$hash_reference{KLÍČ}
$code_reference = \&funkce;
$code_reference->(1,2,3);   # je volání funkce funkce()
                            # to stejné, co $$code_reference(1,2,3)
Chceme-li použít v jednom výrazu několik dereferencí pomocí operátoru ->, je použití tohoto operátoru mezi dvojicí hranatých nebo složených závorek nepovinné.

Máme proměnnou $data typu hash, kde klíči jsou údaje reprezentující čísla roků, hodnotami jsou odkazy na hash, kde klíči jsou názvy měsíců v roce a hodnotami opět odkazy, ale tentokráte na pole, kde jednotlivé položky znamenají obrat firmy v konkrétním dni měsíce. Obrat firmy v roce 2000, dne 15. ledna potom leží na pozici $data->{2000}->{Leden}->[0] (nebo $data->{2000}{Leden}[0].

Pseudohashe

Pseudohashe jsou datové stuktury experimentálně zavedené od verze Perl 5.005. Jsou to odkazy na pole, jejichž prvním prvkem je odkaz na hash. S takovou strukturou lze potom pracovat nejen jako s odkazem na pole, ale také jako s odkazem na hash. Je to možné proto, že pomocí hashe, na který se odkazujeme v prvním prvku pole, je předpis, pomocí kterého se mapují textové řetězce (pomocí nich se přistupuje k prvkům hashe) na číselné indexy (pomocí nich se přistupuje k prvkům pole).
$pseudohash = [{a => 1, b => 2, c => 3}, 'xx', 'yy', 'zz'];
Při vyhodnocování výrazu $pseudohash->{a} se v prvním prvku pseudohashe najde, že pro klíč a se má hledat hodnota v druhém prvku odkazovaného pole (index 1). Při používání pseudohashů dojde k chybě, když se pokoušíme pracovat s prvkem, který nebyl inicializován při vytvoření pseudohashe, nebo kterému nebyla přiřazena nějaká hodnota (i nedefinovaná), nebo pro který vůbec neexistuje klíč.
$pseudohash = [{a => 1, b => 2, c => 3}, 'xx'];
# byla inicializována hodnota pro klíč 'a'
$pseudohash->{b} = 'yy';
# pro klíč 'b' byla přiřazena hodnota (může být i nedefinovaná)

print $pseudohash->{c};
# chyba, dvojice klíč 'c' a hodnota neexistuje

print $presudohash->{d};
# chyba, dvojice klíč 'd' a hodnota neexistuje
# a ani nemůže existovat
Způsobem, jak zabránit takovéto chybě, je použití funkce exists na zjištění, zda dvojice klíč-hodnota vůbec existuje. Jako argument této funkci můžeme předat výraz, který pracuje s pseudohashem jako s odkazem na pole i jako s odkazem na hash.
exists $pseudohash->{KLÍČ};
exists $pseudohash->[0]{KLÍČ}; # nebo $pseudohash->[0]->{KLÍČ}

Symbolické odkazy

Proměnná, která není pevným odkazem a je použita jako odkaz, se interpretuje jako symbolický odkaz. Provádí se to tím způsobem, že obsah proměnné se použije jako součást jména globální proměnné (nefungule pro proměnné lexikálně vymezené).
$jmeno = 'aaa';
$$jmeno = 10;		# do proměnné $aaa se nastavi 
			# hodnota 10
${$jmeno} = 10;		# to stejné
@$jmeno = (1, 2, 3)	# pracuje se s polem @aaa
$funkce = 'f';
&$funkce();		# volá se funkce f()
Použití symbolických odkazů může být nebezpečné, proto je možné ho zakázat pomocí
use strict 'refs';
a opět povolit
no strict 'refs';
Je třeba uvědomit si rozdíl mezi následujícími dvěma zápisy.
${jmeno}      # proměnná $jmeno
${"jmeno"}    # proměnná $jmeno, je to ale symbolický odkaz
Využití konstrukce ${jmeno} je možné např. při vkládání hodnot proměnných do řetězců, aby se odlišilo jméno proměnné od ostatních znaků v řetězci.
$jmeno = 'aaa';
print "${jmeno}bbb;   # vytiskne 'aaabbb'

Složitější datové struktury

Pro uchování dat v operační paměti existuje v Perlu pouze tři datové typy -- jednoduchý skalární typ a seznamové typy pole a asociativní pole (hash). V některých jiných programovacích jazycích existují další datové typy, jako například záznamy, struktury, výčtové typy či množiny.

Seznamové typy v Perlu mohou obsahovat pouze jednoduché skalární hodnoty, není tedy možné přímo vytvářet vícerozměrné datové struktury. I přesto existuje způsob, jakým je možné všechny nedostatky vyřešit.

Záznamy, struktury

V programovacím jazyce Pascal máme k dispozici datový typ záznam, v jazyce C potom typ struktura. V Perlu je možné najít ekvivalent pomocí asociativního pole. Záznam (struktura) je v podstatě složitý datový typ, kde na jednotlivé položky záznamu se odkazujeme pomocí řetězce, který je pojmenováním příslušné položky. Stejně tak v hashi se na konkrétní hodnoty odkazujeme pomocí řetězcových klíčů. Hodnoty hashe pak mohou obsahovat libovolné datové typy či složitější stuktury.
%osoba = (jmeno => 'František Dařena',
          bydliste => 'Brno',
          vek => 24);
Oproti některým jiným jazykům Perl díky tomuto řešení umožňuje s takovými datovými strukturami provádět další operace. Umožňuje získat seznam naplněných položek, pouze hodnoty položek nebo umí provádět přiřazení celých datových struktur najednou.

Jinou možností je použít pole. Nevýhodou je to, že k jednotlivým prvkům se přistupuje pomocí číselných indexů. Pro člověka je ale mnohem snazší pamatovat si, že ke jménu osoby bude přistupovat pomocí řetězce jmeno než pomocí indexu 0. Proto je možným řešením použití proměnných, které budou mít výstižná jména a budou obsahovat číselné hodnoty tvořící indexy pole.

$jmeno = 0;
$bydliste = 1;
$vek = 3;

$osoba[$jmeno] = 'František Dařena';
$osoba[$bydliste] = 'Brno';
$osoba[$vek] = 24;

Vícerozměrná pole

Jak již bylo řečeno v části týkající se polí a seznamů, není možné vytvořit vícerozměrné seznamové struktury. Každý seznam se totiž skládá pouze ze skalárních hodnot. Seznamu uvnitř jiného seznamu vždy ztrácí svoji identitu a jeho prvky se tak stávají prvky druhého seznamu.
@a = (1, 2);
@b = (3, 4,);
@c = (5, 6);
@pole = (@a, @b, @c);
Jestliže do seznamové datové struktury umístíme odkaz na jinou seznamovou strukturu, získáme něco, co je možné nazvat vícerozměrnou datovou strukturou (je třeba pamatovat na to, že použitím odkazu jako hashového klíče požadovaného efektu nedosáhneme).
@a = (1, 2);
@b = (3, 4,);
@c = (5, 6);
@pole = (\@a, \@b, \@c);
Pro vytvoření odkazu byl použit operátor \, je však samozřejmě možné použít jakýkoliv způsob vytvoření odkazu. Byly zmíněny v kapitole o odkazech. Následuje příklad využívající konstruktor anonymního pole.
@pole = ([1, 2],
         [3, 4],
         [5, 6]);
Jednotlivá pole z tohoto vícerozměrného pole získáme pomocí dereference jednotlivých položek.
# původní pole @a
@{$pole[0]}

# původní pole @b
@{$pole[1]}

# původní pole @c
@{$pole[2]}
Znak @ slouží k tomu, aby bylo jasné, že se jedná o pole. Odkaz na pole je umístěn v prvcích pole @pole -- $pole[0] je prvním prvkem atd. Složené závorky okolo tohoto výrazu jsou nutné, protože odkaz je obsažen v něčem složitějším, než je pouhá skalární proměnná.

Prvky prvního pole je možné získa následujícím způsobem:

${$pole[0]}[0]   # hodnota 1
nebo
$pole[0]->[0];   # hodnota 1
V případě, že se v průběhu dereference vedle sebe objeví hranaté závorky, je možné symbol -> mezi nimi vynechat.
$pole[0][0]
Budeme-li vícrozměrné pole vytvářet dynamicky za běhu programu, je vhodné použít konstruktoru anonymního pole.
while (<>) {
    chomp;
    @radek = split /\s+/;
    push @matice, [@radek];
    # nebo pouze push @matice, [split /\s+/];
}

Hashe polí

Dalším případem vícerozměrné datové struktury je hash, jehož hodnoty jsou tvořeny odkazy na pole.
%mesta = ('ČR' => ['Praha', 'Brno', 'Ostrava'],
          'SR' => ['Bratislava', 'Košice'],
          'Polsko' => ['Warszava', 'Krakow', 'Wroclaw'])
K vytvoření polí je opět možné použít konstruktoru anonymního pole či nekterého z dalších způsobů. Jednotlivé seznamy získáme z hashe následujícím způsobem:
@mesta_v_Polsku = @{$mesta{Polsko}};
K jednotlivým prvkům těchto polí přístupujeme pomocí následující dereference:
$hlavni_mesto_Polska = ${$mesta{Polsko}}[0];
nebo
$hlavni_mesto_Polska = $mesta{Polsko}->[0];
U druhého způsobu není nutné psát mezi složenými a hranatými závorkami symbol ->. Je tedy možný zápis
$hlavni_mesto_Polska = $mesta{Polsko}[0];

Pole hashů, hashe hashů

Úplně stejným způsobem jako u dvou předešlých variant je možné jako prvky pole či hodnoty hashe použít odkazy na pole nebo na hashe. Pro vytvoření odkazu na hash je vhodné použít konstruktoru anonymního hashe:
# pole hashů
@pole = ( { klic1 => 'hodnota1',
            klic2 => 'hodnota2'
          },
          { klic3 => 'hodnota3',
            klic4 => 'hodnota4',
            klic5 => 'hodnota5'
          });
 
# hash hashů
%hash = ( hash1 => { klic1 => 'hodnota1',
                     klic2 => 'hodnota2'
                   },
          hash2 => { klic3 => 'hodnota3',
                     klic4 => 'hodnota4',
                     klic5 => 'hodnota5'
                   });
Při dereferenci platí opět pravidlo, že mezi hranatými a složenými závorkami a mezi dvojící složených závorek není třeba psát symbol ->.
$pole[0]->{klic1}
$pole[0]{klic1}
Oba tyto zápisy vyjadřují hodnotu na pozici klic1 v hashi, který se nachází v prvním prvku @pole.
$hash{hash1}->{klic2}
$hash{hash1}{klic2}
Tyto dva zápisy vyjadřují hodnotu na pozici klic2 v hashi, který je odkazován z hodnoty v hashi %hash na pozici hash1.

Ještě složitější struktury

Pomocí výše uvedených pravidel je možné vytvářet v podstatě libovolně rozvětvené datové struktury a implementovat tak například stromy nebo grafy. Skalární hodnoty obsažené v polích nebo v hashích mohou být totiž opět odkazy a tím narůstá i rozměr datových struktur.

Následuje příklad datové struktury, pomocí které by bylo možné uchovávat informace o určité knize. Jednalo by se o hash, jehož klíče by tvořily názvy vlastností knihy -- název knihy, autor, struktura knihy a rejstřík. Název a autor knihy jsou řetězce, jedná se tedy o skalární proměnné. Struktura knihy je už trochu složitější. Kniha se skládá z kapitol, každá kapitola má svůj název a seznam podkapitol. Kapitol je více a záleží na jejich pořadí. Proto je vhodným způsobem jejich zaznamenání uchování v poli (seznamový datový typ, položky jsou seřazené tak, jak jdou po sobě). Pro informace o každé kapitole je vhodné použít hash, neboť je třeba udržet více než jednu informaci (název a podkapitoly) a na pořadí uchování těchto hodnot nezáleží. Název podkapitoly je opět skalární hodnota, podkapitoly jsou uchovány v seznamu (stačí názvy). Rejstřík obsahuje klíčová slovo a seznam stránek, na kterých se tato slova vyskytují. Pro uchování této informace je vhodné použít hash polí.

%kniha = (
   nazev => 'Název knihy',
   autor => 'Autor knihy',
   struktura_knihy => 
           [ {nazev_kapitoly => 'První kapitola',
              podkapitoly => ['podkapitola1',
                              'podkapitola2']
             },
             {nazev_kapitoly => 'Druhá kapitola',
              podkapitoly => ['podkapitola1',
                              'podkapitola2',
                              'podkapitola3']
             },
             {nazev_kapitoly => 'Třetí kapitola',
              podkapitoly => ['podkapitola1',
                               'podkapitola2']
             }
           ],
   rejstrik => { slovo1 => [1, 3, 10],
                    slovo2 => [5, 12],
                    slovo3 => [2, 3, 8]}
);
Název první kapitoly by byl následující:
$kniha{struktura_knihy}->[0]->{nazev_kapitoly};
$kniha{struktura_knihy}[0]{nazev_kapitoly};
${$kniha{struktura_knihy}}[0]->{nazev_kapitoly};
${${$kniha{struktura_knihy}}[0]}{nazev_kapitoly};
Seznam podkapitol první kapitoly je následující pole:
@{$kniha{struktura_knihy}->[0]->{podkapitoly}};
@{$kniha{struktura_knihy}[0]{podkapitoly}};
@{${$kniha{struktura_knihy}}[0]->{podkapitoly}};
@{${${$kniha{struktura_knihy}}[0]}{podkapitoly}};
Název první podkapitoly z první kapitoly je výsledkem následujících výrazů:
$kniha{struktura_knihy}->[0]->{podkapitoly}->[0];
$kniha{struktura_knihy}[0]{podkapitoly}[0];
${$kniha{struktura_knihy}}[0]->{podkapitoly}->[0];
${${$kniha{struktura_knihy}}[0]}{podkapitoly}->[0];
${${${$kniha{struktura_knihy}}[0]}{podkapitoly}}[0];
Je vidět, že způsobů dereference je mnoho. První možností je použití odkazu ve jménu proměnné. Díky nutnosti použít složené závorky kolem odkazů, které jsou složitější než obyčejný skalár (např. prvek pole nebo hashe), se tento zápis stává nepřehledný. Daleko čitelnější je použití operátoru ->. Záleží na každém jedinci, zda preferuje psaní tohoto symbolu mezi každou dvojicí hranatých či kulatých závorek, nebo zda tento symbol vynechává. Oba způsoby je samozřejmě možné kombinovat dohromady (je to vidět ve třetím a čtvrtém případě předchozí ukázky).

Možné chyby

Důležité je uvědomit si, že je-li seznamová proměnná na nejvyšší úrovni také odkazována, symbol -> se musí objevit mezi jménem odkazu a označením konkrétního prvku vždy.
@pole_poli = ([1, 2], [3, 4], [5, 6]);

# první prvek v prvním poli
$pole_poli[0]->[0];
$pole_poli[0][0];
${$pole_poli[0]}[0];

$odkaz_na_pole_poli = [[1, 2], [3, 4], [5, 6]];

# první prvek v prvním poli
$odkaz_na_pole_poli->[0]->[0];
$odkaz_na_pole_poli->[0][0];
${$$odkaz_na_pole_poli[0]}[0];

# špatně, chybí -> na jménem odkazu
$odkaz_na_pole_poli[0][0];
Podlední výraz je napsán chybně, ovšem Perl chybu nezahlásí. Se zapnutými varováními na tuto chybu budeme upozorněni a teprve při použití use strict bude vyvolána chyba.

Výpis datové struktury

Pro naformátovaný a přehledný výpis obsahu datové struktury není nutné vymýšlet vlastní způsob, ale je možné použít standardní moduly Data::Dumper nebo Dumpvalue.

Data::Dumper

Modul Data::Dumper je možné použít standardně, nebo objektově orientovaným způsobem. Je možné použít exportovanou funkci Dumper nebo vytvořit nový objekt a pomocí jeho metody danou strukturu zobrazit.
# standardní způsob
use Data::Dumper;

print Dumper \%kniha;
Funkce Dumper v tomto případě očekává seznam proměnných, jejichž obsah má zobrazit. V případě, že bychom jí předali jako argument hash, bylo by to chápáno tak, že se má tento výpis provést pro každou hodnotu takto vzniklého seznamu. To my ale nechceme, chceme zobrazit hash jako celek. Proto předáváme odkaz na hash.
# objektově orientovaný způsob
use Data::Dumper;

$dumper = Data::Dumper->new([\%kniha],['kniha']);
print $dumper->Dump(%kniha);
V tomto případě je nutné nejprve vytvořit nový objekt pomocí konstruktoru new. Ten jako první argument očekává odkaz na pole jmen proměnných, jejichž obsah budeme chtít vypsat, a jako druhý nepovinný argument opět odkaz na pole, které obsahuje pojmenování těchto proměnných ve výpisu (v opačném případě by tyto proměnné byly pojmenovány VAR1 apod.).

Výstupem obou funkcí je naformátovaný obsah zadané proměnné, jsou použity symboly [ ] a { } pro znázornění, co je pole a co hash, a odsazení, aby bylo poznat, co se nachází na které úrovni.

# použití 
# $dumper = Data::Dumper->new([\%kniha],['kniha']);
# print $dumper->Dump(%kniha);

$kniha = {
     'struktura_knihy' => [
                     {
                      'podkapitoly' => [
                                       'podkapitola1',
                                       'podkapitola2'
                                       ],
                      'nazev_kapitoly' => 'První kapitola'
                     },
                     {
                      'podkapitoly' => [
                                       'podkapitola1',
                                       'podkapitola2',
                                       'podkapitola3'
                                       ],
                      'nazev_kapitoly' => 'Druhá kapitola'
                     },
                     {
                      'podkapitoly' => [
                                       'podkapitola1',
                                       'podkapitola2'
                                       ],
                      'nazev_kapitoly' => 'Třetí kapitola'
                     }
                        ],
     'nazev' => 'Název knihy',
     'rejstrik' => {
                    'slovo3' => [
                                 2,
                                 3,
                                 8
                                ],
                    'slovo1' => [
                                 1,
                                 3,
                                 10
                                 ],
                    'slovo2' => [
                                 5,
                                 12
                                ]
                   },
     'autor' => 'Autor knihy'
       };

Dumpvalue

Tetno modul poskytuje objektově orientované rozhraní a poskytuje řadu metod. Funkce dumpValue slouží k výpisu struktury a obsahu zadané proměnné. Funkce dumpValues dělá totéž, ale pro více hodnot současně. Pomocí funkce dumpvars můžeme vypsat obsahy proměnných celého balíku (případně s omezením na některá jména). Důvod, proč jsou funkcím předávány odkazy na datové struktury, je stejný jako u předchozího modulu.
use Dumpvalue;
my $dumper = new Dumpvalue;

# vypsání obsahu a struktury hashe %kniha
$dumper->dumpValue(\%kniha);
Výpis se v tomto případě od použití modulu Data::Dumper liší v tom, že jsou vypsány i adresy odkazovaných datových struktur.

# vypsání obsahu a struktury proměnných balíku main
$dumper->dumpvars('main');

# vypsání obsahu a struktury proměnných balíku main,
# které se jmenují kniha, obsahují znak I nebo
# neobsahují znak _
$dumper->dumpvars('main', 'kniha', '~I', '!_');
Funkce dumpvars jako svůj první argument očekává jméno balíku. Dalšími volitelnými argumenty mohou být buď obyčejné řetězce (budou vypsány proměnné, jejichž jméno je obsahem řetězce) nebo řetězce začínající znakem ~ nebo !. V tomto případě je zbytek řetězce vyhodnocen jako regulární výraz a budou vypsány proměnné, jejichž jména odpovídají (respektive neodpovídají) zadanému vzoru.
# použití $dumper->dumpValue(\%kniha);
'autor' => 'Autor knihy'
'nazev' => 'Název knihy'
'rejstrik' => HASH(0x1b19394)
   'slovo1' => ARRAY(0x1ac574c)
      0  1
      1  3
      2  10
   'slovo2' => ARRAY(0x1acefdc)
      0  5
      1  12
   'slovo3' => ARRAY(0x1b19358)
      0  2
      1  3
      2  8
'struktura_knihy' => ARRAY(0x1ac56d4)
   0  HASH(0x1acf1b0)
      'nazev_kapitoly' => 'První kapitola'
      'podkapitoly' => ARRAY(0x1acf0cc)
         0  'podkapitola1'
         1  'podkapitola2'
   1  HASH(0x1ac55b4)
      'nazev_kapitoly' => 'Druhá kapitola'
      'podkapitoly' => ARRAY(0x1ac553c)
         0  'podkapitola1'
         1  'podkapitola2'
         2  'podkapitola3'
   2  HASH(0x1ac5674)
      'nazev_kapitoly' => 'Třetí kapitola'
      'podkapitoly' => ARRAY(0x1ac5614)
         0  'podkapitola1'