Image
8.6.2016 0 Comments

Delphi / 2. časť: Ladenie aplikácií I

Späť na úvod >> Späť na seriál

Ladenie patrí k neoddeliteľnej súčasti vývojového cyklu aplikácie. Najrôznejším „muchám“ sa nikdy nemožno vyhnúť, a tak sú ladiace nástroje jednou z najdôležitejších súčastí nielen Delphi, ale aj vývojových nástrojov všeobecne. Hoci sa na prvý pohľad môže zdať, že pojem ladenie vo vzťahu k Delphi znamená iba použitie klávesov F7 a F8, nie je to pravda. Veľmi dôležitým nástrojom ladenia sú výnimky, ktorých správne použitie môže ladenie aplikácie výrazne uľahčiť. Okrem toho je potrebné sledovať varovania kompilátora, pretože tie môžu neraz viesť k odhaleniu chyby, ktorú sme ešte ani nestihli objaviť.

Ako už naznačil nadpis tohto článku, budeme sa venovať ladeniu v Delphi. Aby sme neopomenuli používateľov starších verzií Delphi, začneme najskôr opisom ladiacich možností v Delphi 3. Preberieme si tie najzákladnejšie princípy a postupy ladenia, ktoré je možné (aj keď s určitými obmenami) aplikovať aj na Delphi 5. Žiaľ, používateľov Delphi 5 budem musieť sklamať, pretože opis ladiacich nástrojov špecifických pre toto vývojové prostredie príde na rad až o mesiac. Verím však, že nájdu veľa poučného aj v tomto článku, a prosím ich o trpezlivosť a zhovievavosť.

Základy ladenia

Skôr ako sa pustíme do práce, uvedieme niekoľko základných pravidiel, ktoré by ste mali pri ladení aplikácií dodržiavať. Najzákladnejšie je vypnutie optimalizácie (po ňom treba bezpodmienečne použiť príkaz Build all, aby vypnutie optimalizácie ovplyvnilo všetky súbory projektu). Keby sme to neurobili, neboli by sme v niektorých prípadoch schopní sledovať stav určitej premennej. Namiesto toho by sme iba uvideli hlásenie „Variable inaccessible here due to optimization“. Optimalizačný kompilátor totiž používa postupy, ktoré môžu kód upraviť tak, že debugger sa k premennej jednoducho nedostane. Mimochodom, v nápovedi nájdete upokojujúcu vetu, že takýto zásah (teda optimalizácia) v nijakom prípade neovplyvní funkčnosť vášho kódu. Žiaľ, nie je to celkom pravda, zapnutá optimalizácia totiž môže neraz zapríčiniť vznik problémov. Z toho dôvodu mnoho ľudí (vrátane mňa) optimalizáciu radšej prezieravo vypne a zabudne na ňu. Samozrejme, môže to znamenať určitý pokles výkonu, ja si však dovoľujem tvrdiť, že iba teoretický. Treba si uvedomiť, že optimalizácia sa prejaví iba na zložitejšom kóde, ktorý z prevažnej väčšiny pozostáva z čistého Pascalu, resp. iného programovacieho jazyka (optimalizáciu umožňujú aj iné vývojové prostredia). Predstavte si napríklad, že napíšete procedúru, ktorá manipuluje s dátami, používajúc známe metódy komponentu TTable, ako napríklad First, Next, Prior a pod. Ak bude optimalizácia zapnutá, program ušetrí pár strojových cyklov. Problém je v tom, že volanie rutín ako Prior či First výslednú procedúru aj tak spomalí, takže tých niekoľko usporených taktov je nám, ľudovo povedané, nanič. Keby ste pracovali na triediacom algoritme, to už by bola situácia iná. Ja však predpokladám, že väčšina Delphi vývojárov svoje aplikácie skladá z už hotových súčastí a v tom prípade optimalizácia nehrá veľkú úlohu. Aby som to zhrnul: netvrdím, že optimalizácia je zbytočná, skôr sa domnievam, že väčšina z vás nebude vyvíjať také typy aplikácií, kde by kompilátorom optimalizovaný kód hral úlohu (zámerne píšem „kompilátorom optimalizovaný“, pretože optimalizovať môže aj človek a výsledok je, pochopiteľne, oveľa lepší). Dovoľujem si vám teda odporúčať, aby ste optimalizáciu vypli a zabudli na ňu.

Vráťme sa však k pôvodnej téme. Ďalším pravidlom pri ladení programov je, že Delphi by malo mať prístup k zdrojovým kódom len tých jednotiek, ktoré budeme počas práce na programe modifikovať. Pre lepšie pochopenie uvediem príklad: predstavme si, že sme si prezreli demo súborového manažéra, ktorý sa dodáva s Delphi. Tento demoprogram používa jednotku plnú užitočných funkcií, ktoré by sme radi využili vo vlastných programoch, preto jednotku pridáme do nášho projektu. Všetko síce bude fungovať bezchybne, no nie príliš efektívne. Príkaz Build all spôsobí, že Delphi prekompiluje všetky súbory nášho projektu vrátane tejto jednotky, čo je plytvanie časom. Okrem toho sa môže stať, že počas krokovania programu nedopatrením stlačíte nesprávny kláves, v dôsledku čoho sa dostanete do tela niektorej procedúry či funkcie patriacej do tejto novej jednotky. V tom prípade sa budete musieť zdĺhavo „prekrokovať“ až na koniec tejto procedúry či funkcie, čo veru nikoho nepoteší. Možno budete teraz odporovať, že jednotku zo svojho projektu jednoducho nemôžete vynechať, pretože ju potrebujete. Nuž, vynechať ju ani nie je potrebné, problém sa dá vyriešiť takto: jednotku prekopírujeme do adresára s naším projektom, projekt prekompilujeme a jednotku (teda súbor s príponou PAS) vymažeme. V adresári s naším projektom ostane iba súbor DCU, s ktorým už žiadne problémy nebudú, keďže opätovná kompilácia mu nehrozí. Možno sa teraz pýtate, prečo som odporúčal súbor prekopírovať, a teda ho zdvojiť a zbytočne tak plytvať miestom. Odpoveď je veľmi jednoduchá: ak budete váš projekt zálohovať, bude všetko v jednom adresári a nebudete musieť „behať“ hore-dolu po rôznych zákutiach vášho hard disku a pridávať do výsledného archívu súbory. Okrem toho sa môže stať, že sa rozhodnete určitý adresár vymazať a podľa Murphyho zákonov to bude práve ten adresár, ktorý obsahuje dôležité jednotky. Možno sa vám tieto upozornenia zdajú irelevantné, majú však svoje opodstatnenie. Ak si napríklad nainštalujete RX Library a pri krokovaní náhodou stlačíte nesprávny kláves, budete sa musieť „prekrokovať“ celou plejádou volaní, o ktorých existencii nemáte a ani nemusíte mať ani potuchy, nehovoriac už o tom, že po vybraní príkazu Build all bude spolu s vaším projektom prekompilovaná aj RX Library, čo je niekoľko tisíc riadkov. Ak teda budete mať k dispozícii túto knižnicu (či akékoľvek iné knižnice) aj so zdrojovým kódom, prekompilujte ho a ponechajte iba súbor DCU (súbory PAS môžete napríklad skomprimovať a ponechať v tom istom adresári).

Postup spomenutý v predchádzajúcom odseku by som neodporúčal použiť pri súboroch, ktoré sú priamou súčasťou vášho projektu (mám tým na mysli jednotky, ktoré sme neprebrali, ale sami vytvorili). Teoreticky by to síce možné bolo, podľa môjho názoru by to však prinieslo viac problémov ako úžitku. Keby sme napríklad presunuli zdrojový kód jednotky, po čase by sme mohli zistiť, že ešte nefunguje tak, ako má, a v dôsledku toho by ste zdrojový kód museli prekopírovať späť, upraviť, skompilovať a zdrojový súbor opäť presunúť.

Ďalším argumentom, prečo tento postup neuplatňovať, je fakt, že to jednoducho nie je potrebné: Delphi totiž vždy prekompiluje iba tie súbory, ktoré sa zmenili, prípadne súbory, ktoré so zmenenými súbormi súvisia. Na tomto mieste však treba dodať, že v niektorých prípadoch to môže viesť k závažným problémom, pretože systém občas zmeny nezistí a program potom funguje nesprávne, hoci chyba už bola opravená. Inými slovami, vy ste síce zdrojový súbor zmenili, no kompilátor to nezistil, a preto ho neprekompiloval. Ak si teda chcete byť úplne istí, že vami urobené zmeny sa skutočne premietli do výsledného EXE súboru, použite príkaz Build all. Našťastie takéto „prešľapy“ robí kompilátor iba málokedy, takže sa netreba zdržiavať neustálym používaním uvedeného príkazu.

A ešte jedna veľmi dôležitá rada, ktorú veľa programátorov s obľubou ignoruje: komentujte svoje zdrojové súbory! Žiaľ, smutným faktom je, že komentáre sa nikomu písať nechce, a keď sa dotyčný pozrie na svoj kód o rok neskôr, nevychádza z údivu. Ak je to možné, hneď po dokončení dôležitej časti vášho programu si zapíšte základný princíp, na ktorom je tá-ktorá časť programu založená. V niektorých prípadoch to pomôže viac ako okomentovanie každého riadka kódu.

Na záver úvodnej časti tu mám pre používateľov Delphi 3 jeden malý trik. Viete o tom, že Delphi už od verzie 2 obsahuje okno CPU Window? Toto okienko obsahuje disassemblovaný výpis práve vykonávaného kódu plus niekoľko ďalších zaujímavých informácií. Žiaľ, firma Inprise/Borland ho pred zvedavými zrakmi „delphistov“ z neznámych príčin vedome ukryla. Našťastie je možné toto okno pomerne jednoducho aktivovať aplikovaním nasledujúceho postupu: spustite Registry Editor a nájdite kľúč HKEY_CURRENT_USER\Software\Borland\Delphi\3.0\Debugging. Potom do tohto kľúča pridajte novú reťazcovú hodnotu s názvom EnableCPU a jej hodnotu nastavte na 1. Po opätovnom spustení Delphi 3 sa vám v menu View objaví položka CPU Window.

Ladenie v Delphi 3

Väčšina z vás už určite počula o bodoch prerušenia (breakpoints), ktoré sú azda tým najzákladnejším ladiacim mechanizmom všetkých vývojových prostredí, Delphi nevynímajúc. Sú to určité miesta programu, v ktorých sa normálny beh aplikácie zastaví a kontrolu preberá ladiaci program (v našom prípade je ladiacim programom samotné Delphi, no ladenie je možné aj pomocou špecializovaných ladiacich programov, ako napríklad Borland Turbo Debugger či NuMega SoftICE). Bod prerušenia sa dá nastaviť stlačením klávesu F5, prípadne stlačením malej modrej bodky v ľavej časti okna editora zdrojového kódu. Treba poznamenať, že táto bodka sa objaví iba po prekompilovaní projektu. Takisto je potrebné zdôrazniť, že nie na každý riadok kódu je možné umiestniť bod prerušenia.  Bod prerušenia je možné zaradiť iba na ten riadok, ktorý je v ľavej časti okna označený bodkou. Urobme jeden malý pokus: zaraďme bod prerušenia na riadok začínajúci sa príkazom with. Pri pokuse o spustenie programu sa nám objaví dialógové okno. Delphi nás upozorňuje, že pre daný riadok nebol vygenerovaný nijaký kód, resp. že tento kód bol odstránený optimalizačným systémom. My však môžeme druhú možnosť s istotou vylúčiť, pretože optimalizáciu máme vypnutú. Jediným vysvetlením teda je, že pre daný riadok prekladač nevygeneroval nijaký kód. V nasledujúcom odseku vysvetlíme, čo je príčinou tohto javu.

Iste všetci viete, že programovanie v Delphi či iných programovacích jazykoch pozostáva z dvoch hlavných fáz: napísanie programu a preklad programu (ten sa ešte delí na fázu kompilačnú a linkovaciu, to je však momentálne nepodstatné). Program napísaný vo vyššom programovacom jazyku sa teda preloží do strojového kódu. Na základe tohto tvrdenia by sme sa mohli domnievať, že každý riadok pascalovského kódu sa preloží do niekoľkých strojových inštrukcií. Inými slovami, mohli by sme sa nazdávať, že každý riadok má svoj „strojový ekvivalent“. To však nie je pravda. Mnohé kľúčové slová používané v Delphi (napr. with či implementation) slúžia iba ako oporné body pre kompilátor, do strojového kódu sa neprekladajú. Zámerne píšem „mnohé“, pretože v niektorých prípadoch sa do strojového kódu prekladajú príkazy, o ktorých by si to človek nemyslel. Pozrite sa ešte raz na obrázok č. 1: na začiatku procedúry je vedľa príkazu begin bodka. Pokročilejší z vás iste vedia, že kompilátor na tento príkaz zareaguje vytvorením tzv. štandardného rámca zásobníka (standard stack frame), čo je vo väčšine prípadov inštrukcia PUSH EBP, prípadne niekoľko ďalších inštrukcií PUSH. To už sú však nepodstatné detaily, dôležité je uvedomiť si, že nie na každý riadok je možné zaradiť bod prerušenia.

Ukážkové programy, s ktorými budeme pracovať, budú veľmi jednoduché a zámerne chybne napísané, pretože keby fungovali správne, princípy ladenia by sme si na nich veru ukázať nemohli. Dajme sa teda do práce.

Jadrom nášho prvého programu bude procedúra, ktorá vykoná dopyt SQL, pričom samotný SQL príkaz dostane ako parameter. Volať ju budú dve rutiny, prvá sa aktivuje po stlačení prvého tlačidla (nazvaného FirstBtn) a druhá po stlačení druhého tlačidla (nazvaného SecondBtn). Komponent TQuery, ktorý bude mať za úlohu spracovať dopyt SQL, som nazval Query. Po stlačení prvého tlačidla nastane chyba, po stlačení druhého celý proces prebehne správne. Uvedené procedúry majú nasledujúci tvar:

 

procedure TForm1.DummyProc(SQLString:string);

begin

try

 with query do

 begin

  Close;

  SQL.Clear;

  SQL.Add(SQLString);

  Open;

 end;//with

 except

   raise

 end;//except

ShowMessage('OK');

end;

Ako vidíme, táto procedúra je založená na veľmi jednoduchom princípe: ak sa počas jej vykonávania vyskytne chyba (výnimka), program skočí na príkaz raise a procedúra ShowMessage sa nikdy nevykoná. Samotné načítanie SQL príkazu prebehne tak, že sa najprv predchádzajúci príkaz vymaže metódou Clear a nový príkaz sa pridá pomocou metódy Add (nezabúdajte, že keby sme nepoužili metódu Clear, počet riadkov SQL skriptu by sa neustále zvyšoval).

Zvyšné dve procedúry, z ktorých bude uvedená rutina volaná, vyzerajú takto:

procedure TForm1.FirstBtnClick(Sender: TObject);

begin

  DummyProc('select orders from animals');

end;

 

procedure TForm1.SecondBtnClick(Sender: TObject);

begin

  DummyProc('select * from animals');

end;

Program spustíme a otestujeme. Jeho cieľom je demonštrovať situáciu, keď je jedna a tá istá rutina volaná z viacerých miest programu. Chybu spôsobí prvá procedúra, ktorá rutine DummyProc odovzdá príkaz odkazujúci na neexistujúce pole. Samotná rutina DummyProc môže byť napísaná správne, no v dôsledku nesprávnych parametrov sa môžu vyskytnúť problémy. V takom prípade je potrebné zistiť, ktorá procedúra (alebo procedúry) volaniu tejto rutiny predchádzala, a teda jej mohla odovzdať nesprávne parametre. Presne na tento účel slúži okno Call Stack: ukazuje nám zoznam volaných rutín, pričom najskôr volaná rutina je na poslednom mieste zoznamu a naposledy volaná rutina je na prvom mieste zoznamu. Zatiaľ teda vieme, že rutina DummyProc v jednom prípade dostane dobrý a v druhom prípade zlý parameter. Keďže zlý parameter spôsobí vyvolanie výnimky, program začne vykonávať príkaz raise. Z toho dôvodu na tento príkaz umiestnime bod prerušenia a otvoríme okno Call Stack. Program spustíme a stlačíme prvé tlačidlo (teda tlačidlo FirstBtn). Ako vidíme, výnimka nastala bezprostredne za volaním procedúry DummyProc, okno Call Stack nám však zatiaľ neukazuje potrebné informácie, pretože sa ešte nezačala vykonávať obslužná rutina výnimky v procedúre DummyProc. Stlačíme teda kláves F9 a program skočí na príkaz raise. Okno Call Stack bude vyzerať podobne ako jeho „kolega“ . Teraz už vieme, aké bolo poradie volania jednotlivých funkcií, a teda vieme zistiť, odkiaľ rutina DummyProc dostala nesprávny parameter.

Keďže náš ukážkový program je veľmi jednoduchý, vieme chybu rýchlo odstrániť a program opätovne prekompilovať. Môže však nastať situácia, keď sú vaše prsty rýchlejšie ako mozog a stlačia F9 skôr, ako si uvedomíte, že ste síce chybu opravili, ale inú, možno menšiu chybu ste opraviť zabudli. Prestavte si, že ste SQL príkaz v prvej procedúre opravili na správny, slovko Orders ste teda nahradili hviezdičkou. Nedopatrením ste sa však „uklepli“ a medzi slová Orders a From ste zabudli dať medzeru. Kým sa svoju chybu snažíte oľutovať, program sa rozbehne. Čo teraz? Prvou možnosťou je program ukončiť, opraviť a prekompilovať. V našom prípade bude potom všetko pracovať správne, štruktúra aplikácie je jednoduchá a nie je problém chybu v priebehu niekoľkých sekúnd lokalizovať. V zložitejších programoch to však nemusí platiť, oprava chyby môže viesť k odhaleniu ďalších skrytých chýb. Aby sme neplytvali čas opakovanou kompiláciou, ukážeme si, ako zmeniť obsah premennej počas behu programu.

Keď si pozorne preštudujete procedúru DummyProc, možno dospejete k záveru, že najzrelším kandidátom na úpravu bude premenná SQLString, parameter tejto procedúry. Ale pozor, parametre by ste nemali nikdy meniť, pretože to môže viesť k pádu celého Delphi. Jedným z možných riešení by bolo zaviesť lokálnu premennú, ktorá by prebrala hodnotu premennej SQLString, pričom rutina by ďalej pracovala už iba z touto premennou. To však nie je potrebné, pretože my môžeme pracovať priamo s vlastnosťou SQL komponentu TQuery, ktorá je typu TStrings. Aby sme si boli istí, že po našej „umelej“ zmene sa SQL skript už nezmení, zaradíme bod prerušenia na príkaz Open. Ak by sme totiž umiestnili bod prerušenia napríklad na príkaz Add či na iný príkaz, ktorý mu predchádza, nemohli by sme jednoducho zmeniť nič, pretože až príkaz Add spôsobí pridanie chybného SQL príkazu, ktorý potom musíme opraviť. Mohlo by sa stať aj to, že síce chybný SQL príkaz opravíte, bod prerušenia je však zaradený práve na ten príkaz, ktorý vlastnosť SQL komponentu TQuery nejakým spôsobom modifikuje, v dôsledku čoho bude SQL príkaz opäť zlý. Ak však bude bod prerušenia „sídliť“ na príkaze Open, máte úplnú istotu, že sa vlastnosť SQL už nezmení, a teda vami urobené zmeny či opravy nebudú ignorované.

Zmeniť hodnoty premenných počas behu programu je možné prostredníctvom príkazu Evaluate/Modify, ktorý vyvoláme z kontextového menu. Do rozbaľovacieho zoznamu napíšeme výraz query.SQL[0] a stlačíme tlačidlo Evaluate. Na obrázku č. 4 vidíme, že vlastnosť SQL skutočne obsahuje nesprávny reťazec (pozri okno Result), ktorý je prístupný v poli New Value, a teda ho môžeme opraviť (na obrázku vidíme opravenú verziu). Ak teraz stlačíme tlačidlo Modify, zmeny sa premietnu do programu a my sme si ušetrili jednu kompiláciu. Samozrejme, túto chybu bude potrebné v zdrojovom kóde tak či tak opraviť, takže sa vám možno celý postup zdal zbytočný. Môžete si však byť istí, že pri písaní väčších programov vám funkcia Evaluate/Modify neraz príde vhod.

Náš program je teda odladený, body prerušenia preto môžeme odstrániť. Ladenie väčších aplikácií je však komplikovanejšie, preto neraz zistíme, že program predsa len nefunguje tak, ako by mal, a body prerušenia musia späť na svoje miesto. Ak si nie ste celkom istí, že program bude pracovať správne, body prerušenia neodstraňujte, iba ich deaktivujte. To je možné urobiť prostredníctvom kontextového menu v okne Breakpoint List.

Medzi zaujímavé vlastnosti bodu prerušenia patrí to, že nemusí byť aktívny vždy, môže sa aktivovať sám vo chvíli, keď je splnená určitá podmienka. Práve túto schopnosť debuggera si ukážeme na druhom ukážkovom programe. Ten bude využívať komponent TQuery, na rozdiel od predchádzajúceho príkladu však bude obsahovať trošku viac kódu, pretože jeho úlohou bude zistiť zoznam polí komponentu TQuery a zobraziť ho v komponente TListBox. Samozrejme, aj tento program bude obsahovať chybu.

Pôvodný kód predchádzajúceho programu odstránime a nahradíme ho novým. Na formulár pridáme komponent typu TListBox, ktorý nazveme Polia. Vlastnosť SQL komponentu TQuery bude obsahovať príkaz

select * from animals

Samotný kód, ktorého úlohou bude načítať zoznam polí, má nasledujúcu podobu:

procedure TForm1.FirstBtnClick(Sender: TObject);

var i:integer;

begin

 Query.Close;

 Query.Open;

 Polia.Items.Clear;

 for i :=0 to Query.FieldCount do

  Polia.Items.Add(Query.Fields[i].FieldName);

end;

Po spustení programu sa komponent TListBox síce naplní, no na konci cyklu vznikne výnimka „List index out of bounds (5)“. Číslo 5 v zátvorke je neklamným znamením toho, že problém nastane pri piatom prechode cyklom. Zrejme už tušíte, ktorý riadok bude príčinou vzniku výnimky. Našu teóriu si však musíme overiť, preto umiestnime bod prerušenia na predposledný riadok. Mimochodom, všimnite si, že riadok začínajúci sa cyklom for je rozdelený na dve časti, pričom kód sa generuje pre každú z nich (t. j. aj prvý, aj druhý riadok majú v ľavej časti okna editora bodku). V tomto prípade riadok musí byť rozdelený, pretože inak by bod prerušenia s podmienkou nefungoval. Po zaradení bodu prerušenia sa presunieme do okna Breakpoint List, kde z kontextového menu vyberieme položku Properties. Zobrazí sa nám dialógové okno. Presnejšie povedané, vyplníme iba riadok Condition, pretože Delphi ostatné položky vyplní za nás, a následne stlačíme tlačidlo Modify. Po týchto úpravách sa nám beh programu preruší, len čo premenná i nadobudne hodnotu 5.  Potvrdila sa teda naša teória, že problémy spôsobil predposledný riadok, cyklus má totiž vyzerať takto:

for i :=0 to Query.FieldCount-1 do

  Polia.Items.Add(Query.Fields[i].FieldName);

Príkaz Assert

Tým z vás, ktorí programovali v jazyku C++, akiste netreba príkaz assert osobitne predstavovať. Ide o príkaz, ktorý preberá ako parameter výraz typu boolean. Ak je hodnota výrazu true, nestane sa nič, ak však výraz nadobudne hodnotu false, vznikne výnimka „Assertion failure“. Aby vám však tento príkaz fungoval, musíte mať v nastaveniach Delphi zaškrtnutú voľbu Assertions.

Ak patríte alebo ste patrili medzi náruživých hráčov, ktorý „hltali“ každú demoverziu hry, je celkom pravdepodobné, že ste sa s týmto príkazom už stretli. Ja som sa s ním dostal prvýkrát do kontaktu niekedy okolo roku 1994, keď som hral demoverziu Dark Forces. Veselo si chodím, strieľam zloduchov a zrazu čierna obrazovka. Najprv som si myslel, že „spadol“ DOS4G/W (extender, ktorý hra používala), no potom som si prečítal chybové hlásenie, ktoré znelo „Assertion failed“. Dokonca bol na obrazovke vypísaný aj názov C súboru spolu s riadkom, kde problém nastal (žiaľ, ani názov súboru, ani číslo riadka si už nepamätám). Druhý kontakt bol iba nepriamy: v istom nemenovanom hernom časopise sa istý čitateľ sťažoval, že mu istá hra neustále padala a vypisovala niečo ako „Assertion failure“. Problém vyriešil až najnovší patch. Ako vidíme, tento príkaz sa používa pomerne často, preto by sme sa ho mali naučiť používať aj my.

Vráťme sa však späť k pôvodnej téme. Hoci by sa mohlo zdať, že príkaz assert je možné nahradiť príkazom typu

if Variable=true then....

nie je to celkom tak. Príkaz Assert totiž nevypisuje iba hlásenie, ale aj presné číslo riadka a názov súboru, ktorý výnimku spôsobil. Najjednoduchší spôsob, ako si príkaz vyskúšať, je takýto:

procedure TForm1.Button1Click(Sender: TObject);

begin

  Assert(false);

end;

Tento riadok spôsobí zobrazenie chybového hlásenia. Praktické využitie tohto príkazu závisí predovšetkým od vás. Ja osobne som ho začal používať, keď som pracoval na jednom väčšom programe. Obsahoval viacero databáz, pričom kód na určitom mieste programu databázu zatvoril, v dôsledku čoho som potom musel trpieť hlásenia typu „Cannot perform this operation on a closed dataset“. Riadok, ktorý databázu ilegálne zatváral, som našiel práve prostredníctvom príkazu assert: jednoducho som viacero týchto príkazov rozmiestnil okolo miesta problému a túto „slučku“ som postupne zužoval. Hľadaný riadok sa mi nakoniec podarilo nájsť a chybu odstrániť.

Nabudúce

Nabudúce budeme pokračovať v rozoberaní problematiky ladenia aplikácií. Povieme si, ako nám pri ladení môžu byť užitočné výnimky, a ukážeme si možnosti ladenia v Delphi 5. Dovtedy vám prajem veľa úspechov pri „vychytávaní múch“ vo vašich programoch.


Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to

Tipy a triky: Ako na snímku obrazovky na akomkoľvek počítači s Windows?

02.12.2016 00:13

Ak snímky obrazovky robíte často apotrebujete napríklad funkcie na posun stránok alebo snímanie zobrazenia pri vyššom rozlíšení displeja, zrejme používate nejakú špecializovanú aplikáciu. Väčšina použ ...

Ako na to 1

Tipy a triky: Ako aplikácii prednastaviť spúšťanie s administrátorskými právami?

30.11.2016 00:10

Väčšina aspoň trochu skúsenejších používateľov vie, že aj keď máte na operačnom systéme Windows vytvorený administrátorský účet, aplikácie pre bezpečnosť nefungujú vždy splnými administrátorskými práv ...

Ako na to 2

Tipy a triky: Ako vypnúť uzamykaciu obrazovku vo Windows 10?

29.11.2016 00:10

Rozčuľuje vás, že pred každým prihlásením doúčtu vášho počítača musíte prejsť uzamykacou obrazovkou? Windows 10 na tejto obrazovke ukazuje čas,dátum anejakú zaujímavú fotografiu zrôznych kútov sveta. ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá