LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (45) - Odkazy

V dnešním díle otevíráme další velké téma, jímž je problematika odkazů.

24.10.2006 06:00 | Jiří Václavík | Články autora | přečteno 14887×

Dodnes jsme si pod pojmem datová struktura vybavovali skalár, pole a hash. Odkazy jsou prostředkem, který otevírá dveře ke složitějším. Díky nim budeme moci implementovat takové struktury jako pole polí hashů. Pomocí odkazů lze pracovat s daty daleko lépe než dosud a prakticky neomezeně se v tomto směru rozšíří naše možnosti.

Přes to všechno není odkaz nic jiného než zvláštní typ skalární proměnné. Proto se píše normálně s předponou $.

Odkazy nyní rozdělíme na 2 kategorie: pevné odkazy a symbolické odkazy. V tomto a následujících dílech se budeme věnovat zejména těm pevným; symbolické zmíníme pouze letmo.

Pevné odkazy

Pevný odkaz (dále jen odkaz) má speciální obsah. Je v něm uložena adresa v paměti. Pokud hodnotu odkazu - tedy adresu - vytiskneme, uvidíme řetězec ve tvaru DATOVÝ_TYP(adresa) - konkrétně například SCALAR(0x8187a3c). Odtud je zřejmé, že Perl zde zavádí typovou kontrolu. To má za následek, že pokud budeme chtít s odkazem na skalár zacházet jako s odkazem na pole, skončí program chybou.

Odkaz na skalár

Teď už k věci. Vytvoříme 1. odkaz. Abychom tak mohli učinit, musíme vytvořit nějakou proměnnou s hodnotou.

$x = "HODNOTA";

V paměti to nyní vypadá zjednodušeně takto:

AdresaHodnotaProměnná
3
4
5"HODNOTA"$x
6
7
8
9
10
11

A teď vytvoříme na onu proměnnou odkaz. To se dělá stejně jako přiřazení proměnné, jen se před přiřazovanou hodnotu zapíše zpětné lomítko.

$ref_x = \$x;

$ref_x je skalární proměnná typu odkaz. Situace v paměti se změnila.

AdresaHodnotaProměnná
3
4
5"HODNOTA"$x
6
7
8
9
10SCALAR(5)$ref_x
11

Popišme si, co údaje v tabulce znamenají. Na adrese 10 je uložena hodnota proměnné $ref_x. Tou je odkaz na jinou adresu - konkrétně na adresu 5, na které leží hodnota typu SCALAR s obsahem "HODNOTA". Lze tedy říci, že $ref_x ukazuje na adresu 5, kde je uložena hodnota "HODNOTA".

Nyní můžeme k hodnotě na adrese 5 přistupovat dvěma způsoby. Tak jako dosud, pomocí $x, nebo nově i přes odkaz $ref_x (jediné místo v paměti má 2 jména). Přístupu k hodnotě přes odkaz se říká dereferencování a uskutečňuje se uvedením dolaru mezi stávající dolar a identifikátor. Hodnotu na adrese 5 tedy můžeme tisknout jedním z těchto dvou příkazů, podle dané situace.

print $$ref_x;
print $x;

Perl si počet pevných odkazů, které ukazují na určité místo v paměti, počítá. Počet odkazů se dokáže nejen zvyšovat (vytvářením odkazů na dané místo v paměti), ale i snižovat (zánik nebo přepsání proměnných). Pokud takto klesne na 0, ztrácí se informace o umístění hodnoty. V takovém případě je hodnota zrušena pomocí automatického mechanizmu (tzv. garbage collection) a paměť se uvolní.

Stejný systém správy funguje v souborovém systému, kde je počet odkazů pro každý i-uzel také udržován. Počet odkazů je jednou z informací získaných příkazem ls -l.

Spiše jako zajímavost si uveďme, že za jistých okolností může nastat situace, kdy proměnná $x ukazuje na proměnnou $y a zároveň $y ukazuje na $x. Tomu se říká cyklický odkaz. Po skončení platnosti obou proměnných nemůže být místo v paměti uvolněno, protože čítač odkazů stále neklesl na 0. Pokud to nastane, nezpůsobí to prakticky žádné problémy. Ty nastávají až tehdy, když se tento efekt kumuluje. Zkuste si tento příklad (ale ještě předtím si vše rozdělané uložte) a sledujte paměťové zatížení například pomocí nástroje top.

while(1){
    my($x, $y);
    $x = \$y;
    $y = \$x;
}

Odkaz na pole

Podobně se pracuje s odkazy na pole. Při práci s polem jako s celkem se syntaxe liší pouze nezbytným nahrazením úvodního dolaru za zavináč.

@pole = (5, 6, 7, 8);
$r_pole = \@pole;
print @$r_pole; #tiskne 5678

Zajímavější je to s prvky polí. Z jediného odkazu získáváme přístup k celému poli. Pouze přidáme na konec zápisu dereferencovaného odkazu index. Prvek s indexem 2 se tiskne takto.

print $$r_pole[2]; #tiskne 7

Takový zápis může být značně nejasný. Na první pohled (a často ani na druhý) není zřejmé, kde provádění začíná. Vyhodnotí se nejdříve $$r_pole nebo $r_pole[2]? Lze pouze konstatovat, že správně je $$r_pole. Dereference má vždy vyšší prioritu než index v [].

Z tohoto důvodu se zavádí ještě další a na pohled jednoznačná syntaxe. Mezi název proměnné a index nebo klíč se vloží šipka. Tyto zápisy přístupu k prvku pole jsou stejné.

print $$r_pole[0];
print $r_pole->[0];

Odkaz na hash

Pro hashe platí stejný postup jako při práci s polem. Platí to jak při práci s hashem jako celkem, tak s jednotlivými prvky.

%hash = ("a" => 1);  #vytvoření hashe
$r_hash = \%hash;    #vytvoření odkazu na hash
print $$r_hash{"a"}; #přístup k prvku přes odkaz na hash
print $r_hash->{"a"};#to samé s použitím šipkové notace

Odkaz na podprogram

Nejen na typy skalár, pole a hash jde vytvořit odkaz. Důkazem toho je možnost odkazu na podprogram. Ačkoliv je tento typ odkazu možná hůře představitelný, systém je úplně stejný, jako v předchozích příkladech. Adresu získáme pomocí operátoru zpětného lomítka, tu přiřadíme do proměnné a pomocí ní můžeme po dereferenci volat podprogram.

sub tisk { print "Podprogram\n"; }

$r_print = \&tisk;

&$r_print();
&tisk();

Poslední 2 příkazy volaly tutéž proceduru. Podprogram tisk má nyní 2 jména.

Lze samozřejmě použít šipkovou notaci a případně i předat argumenty.

$r_code = \&delej_neco;
$r_code->(1, 2, 3)

Ale pozor - za jméno dereferencovávaného podprogramu se nesmí uvést závorky. V takovém případě by se podprogram provedl dříve, než se vytvořil odkaz. Do proměnné by se tak přiřadil odkaz na návratovou hodnotu podprogramu.

Úprava dat pomocí odkazů

Doteď jsme data jen získávali. Pokud chceme data, na které odkazy ukazují, upravovat, musíme si uvědomit, co se děje v paměti. Přestavme si, že máme proměnnou $x a odkaz $r_x. Ten ukazuje na hodnotu proměnné $x.

$x = "HODNOTA";
$r_x = \$x;

Zápis na místo, kam ukazuje odkaz, provedeme, stejně jako při čtení hodnoty, dereferencí.

$$r_x = "JINA HODNOTA";

A teď vypišme hodnoty, na které ukazují $$r_x a $x.

print $$r_x;#tiskne "JINA HODNOTA"
print $x;   #tiskne "JINA HODNOTA"

Přestože jsme upravili pouze $$r_x, novou hodnotu má i proměnná $x. Vysvětlení nabízí reprezentace v paměti. Obě proměnné ukazují na stejnou adresu paměti. Změnou hodnoty na této adrese se tedy změní všechny hodnoty získané dereferencováním proměnných, které na toto místo ukazují. Přesněji řečeno jedna hodnota, protože $$r_x je vlastně jen aliasem pro $x.

Symbolické odkazy

Pokud je zapsána proměnná tak, jako by byla pevným odkazem, ale pevným odkazem není, jde o symbolický odkaz. Máme-li proměnnou $$prom v případě pevných odkazů, samotné $prom obsahuje adresu v paměti. Symbolické odkazy se liší tím, že $prom není odkazem a místo toho obsahuje řetězec. Symbolické odkazy nejsou v pravém smyslu odkazy.

$delka = 186;
$prom = "delka";
print $$prom;

Hodnota proměnné $prom se stává jménem jiné proměnné. $delka a $$prom jsou aliasy, takže bylo vytisknuto 186.

Úplně stejně to funguje pro jiné datové typy.

@xx = (2, 3, 6);
$prom = "xx";
print @$prom[0];

Symbolické odkazy nelze v režimu strict (přesněji strict "refs") používat.

Verze pro tisk

pridej.cz

 

DISKUZE

Odkazy 24.10.2006 13:53 Igor Bujna




Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

5.3.2017 19:12 /Redakce Linuxsoft.cz
PR: 23. března proběhne v Praze konferenci na téma Cloud computing v praxi. Hlavními tématy jsou: Nejžhavější trendy v oblasti cloudu a cloudových řešení, Moderní cloudové služby, Infrastruktura současných cloudů, Efektivní využití cloudu, Nástrahy cloudových řešení a jak se jim vyhnout.
Přidat komentář

27.2.2017 22:12 /František Kučera
Pozvánka na 137. sraz OpenAlt – Praha: Tentokrát jsme si pro vás připravili neobvyklou akci. Ve středu 1.3. v 17:30 nás přivítá sdružení CZ.NIC ve svých prostorách v Milešovské ulici číslo 5 na Praze 3, kde si pro nás připravili krátkou prezentaci jejich činnosti. Následně navštívíme jejich datacentrum pod Žižkovskou věží. Provedou nás prostory, které jsou běžnému smrtelníkovi nedostupné!
Po ukončení prohlídky se všchni odebereme do hostince U vodoucha, Jagelonská 21, Praha 3 pochutnat si na některém z vybraných piv či dát si něco na zub. Rezervaci máme od 19:30, heslo je OpenAlt.
Ale pozor! Do prostor datového centra máme omezený přístup, dostane se tam pouze 10 lidí! Takže kdo přijde dříve, ten má přednost, a občanky s sebou! Kdo nebude chtít na prohlídku datového centra, může se pomalu přesunout do hostince U vodoucha a u nepřeberné nabídky piv počkat na ostatní.
Přidat komentář

18.1.2017 0:49 /František Kučera
Členové a příznivci spolku OpenAlt se pravidelně schází v Praze a Brně. Fotky z pražských srazů za uplynulý rok si můžete prohlédnout na stránkách spolku. Příští sraz se koná už 19. ledna – tentokrát je tématem ergonomie ovládání počítače – tzn. klávesnice, myši a další zařízení. Také budete mít příležitost si prohlédnout pražský hackerspace Brmlab.
Přidat komentář

8.1.2017 17:51 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 19. ledna od 18:30 v pražském hackerspacu Brmlab. Tentokrát je tématem srazu ergonomie ovládání počítače – tzn. klávesnice, myši a další zařízení. K vidění bude mechanická klávesnice dasKeyboard, trackball Logitech nebo grafický tablet (a velký touchpad) Wacom. Přineste i vy ukázat svoje zajímavé klávesnice a další HW. V 18:20 je sraz před budovou, v 18:30 jdeme společně dovnitř, je tedy dobré přijít včas. Podle zájmu se později přesuneme do nějaké restaurace v okolí.
Přidat komentář

1.12.2016 22:13 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 8. prosince od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Sraz bude tentokrát tématický. Bude retro! K vidění budou přístroje jako Psion 5mx nebo Palm Z22. Ze svobodného hardwaru pak Openmoko nebo čtečka WikiReader. Přijďte se i vy pochlubit svými legendami, nebo alespoň na pivo. Moderní hardware má vstup samozřejmě také povolen.
Komentářů: 1

4.9.2016 20:13 /Pavel `Goldenfish' Kysilka
PR: Dne 22.9.2016 proběhne v Praze konference Cloud computing v praxi. Tématy bude např. nejnovější trendy v oblasti cloudu a cloudových řešení, provozování ERP v cloudu, o hostování různých typů softwaru, ale třeba i o zálohování dat nabízeném podnikům formou služby.
Přidat komentář

1.9.2016 11:27 /Honza Javorek
Česká konference o Pythonu, PyCon CZ, stále hledá přednášející skrz dobrovolné přihlášky. Máte-li zajímavé téma, neváhejte a zkuste jej přihlásit, uzávěrka je již 12. září. Konference letos přijímá i přednášky v češtině a nabízí pomoc s přípravou začínajícím speakerům. Řečníci mají navíc vstup zadarmo! Více na webu.
Přidat komentář

27.8.2016 8:55 /Delujek
Dnes po 4 letech komunitního vývoje vyšla diaspora 0.6.0.0
diaspora* je open-source, distribuovaná sociální síť s důrazem na soukromý
Více v oficiálním blog-postu
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

24.3.2017 11:54 / Hui
country cottages

16.3.2017 16:33 / BezvaDesign.cz
Re: Hledám grafika do teamu

9.3.2017 11:44 / Jaromir Obr
Re: chyba

18.1.2017 20:18 / martin horky
Spolupraca linuxu a microsoftu

17.1.2017 9:57 / Pavel Hrubeš
Re: Externí USB televizní karta

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze