Dar vieno analitiko svetainė

Petras Kudaras

Perlo objektai: antra dalis

Pagalvojimai apie ateitį: geresni konstruktoriai

Nors šiuo metu dar gal ir nežinote kas yra paveldimumas, bet kažkada ateityje matyt teks su tuo susidurti. Tam, kad paveldimumas veiktų kaip turėtų, reikia naudoti bless() sudviem argumentais. Antruoju argumentu yra perduodama klasė, į kurią bus „palaiminama“. Tuo pačiu padarysime konstruktorių lankstesnį, kad būtų jį galima iškviesti tiek kaip klasės, tiek kaip ir objekto metodą. T.y. kad būtų galima rašyti:

$as = Asmuo->naujas();
$ji = $as->naujas();

Viskas ką mums reikia padaryti, tai patikrinti ar į konstruktorių buvo perduota nuoroda (reference) ar ne. Funkcija buvo iškviesta kaip objekto metodas jeigu buvo perduota nuoroda – tokiu atveju reikia sužinoti kas tai per klasė naudojantis funkcija ref(). Jei perduota ne nuoroda, o paprasčiausias klasės pavadinimas, tai juo ir naudojamės (tokiu atveju funkcija iškviesta kaip klasės metodas).

sub naujas {
        my $perduota = shift;
        my $klase = ref($perduota) || $perduota;
        my $mano  = {};
        $mano->{VARDAS}   = undef;
        $mano->{AMZIUS}   = undef;
        $mano->{KOLEGOS}  = [];
        bless ($mano, $klase);
        return $mano;
    } 

Štai ir viskas ką reikia žinoti apie konstruktorius. Jie suteikia objektams gyvenimą grąžindami nuorodas į supakuotus nepermatomus daiktus vadinamus objektais. Po to šiuos objektus galima naudoti iškviečiant jų metodus.

Destruktoriai

Viskas kas turi pradžią, turi ir pabaigą. Objekto pradžia yra konstruktoriaus metodas, o pabaiga – destruktorius. Destruktorius yra metodas, kuris automatiškai iškviečiamas tada kai objektas nustoja egzistuoti. Destruktoriai Perle turi būti pavadinti funkcijos vardu DESTROY ir naudojami atlikti švarinimo darbus (uždaryti atidarytas bylas, soketus, ir panašiai)

Kodėl konstruktoriai gali vadintis kaip nori, o detruktoriai ne? Tai yra būtina todėl, kad konstruktorius iškviečia pats programuotojas, o destruktoriai yra iškviečiami automatiškai paties interpretatoriaus (per garbage collection mechanizmą). Todėl reikia destruktorių vadinti vardu DESTROY tam kad Perlas žinotų ką iškviesti. Perlas neduoda garantijų kad DESTROY bus iškviestas tuoj po objekto sunaikinimo – jis iškviečiamas kada patogiau pačiam Perlui, todėl destruktoriuje į tai reikia atsižvelgti.

Kodėl DESTROY rašomas visomis didžiosiomis raidėmis? Perlas turi tradiciją vadinti visas funkcijas, kurios bus iškviečiamos pačio interpretatoriaus, o ne programuotojo vadinti didžiosiomis raidėmis. Panašiai yra su BEGIN, END, AUTOLOAD bei visais metodais priklausančiais tie mechanizmui (žr. perltie dokumentaciją)

Objektinėse kalbose dažniausiai visai nereikia sukti galvos kada bus iškviestas destruktorius. Jis iškviečiamas tada kada reikia. Žemo lygio programavimo kalbose, kuriose nėra automatinio atminties valdymo niekaip neįmanoma padaryti taip, kad destruktorius būtų iškviestas automatiškai jį sunaikinus – tam programuotojas pats turi iškviesti desktruktorių ir atlaisvinti atmintį ir kitus resursus. Perle, ne taip kaip C++, objektų destruktoriai retai reikalingi, o jei jie ir reikalingi tai jie iškviečiami automatiškai. Mūsų klasėje Asmuo mums nereikia destruktoriaus, nes Perlas pats pasirūpina tokiais paprastais dalykais kaip atminties atlaisvinimas.

Vienintelė situacija, kai Perlo magija gali nesuveikti gali būti tokia, kai naudojama duomenų struktūra, rodanti į pati save:

$sitas->{BETKAS} = $sitas;

Tokiu atveju reikia ištrinti tokią nuorodą į save pačiam, jei nenorite kad programa naudotų vis daugiau atminties (memory leak). Tiesa, kai programa baigia darbą, visa atmintis grąžinama, tad kažkada ji bus atlaisvinta, išskyrus atvejus kai ji niekada nebaigia darbo.