Assertion v Delphi - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Assertion v Delphi

java

24. dubna 2002, 00.00 | Narozdíl od Javy se v Delphi již delší dobu objevuje klíčové slovo Assert. A právě v tomto článku se podrobněji podíváme na to jakým způsobem ho používat.

Narozdíl od Javy se v Delphi již delší dobu objevuje klíčové slovo Assert. A právě v tomto článku se podrobněji podíváme na to jakým způsobem ho používat.

Assertions se uvádí jako pomůcka při programování. Přesněji řečeno pro ladění programů. Klíčové slovo Assert vcelku úzce souvisí s výjimkami. Přesněji řečeno ona to výjimka je, i když taková trochu zvláštní, alespoň co se zápisu týče.

Ale co se týká účelu, tak ten je zhola stejný jako výjimka. Při záporném spuštění aserce se ukončí program. Spouštíte-li program přímo z Delphi nejdříve vyskočí výjimka EAssertionFailed v jejímž textu je uveden název souboru a řádek na kterém vznikla. Následně vznikne run-time error 217 1, který ukončí celý program. I když ne vždy to tak musí dopadnout (viz. dále). V dokumentaci se uvádí, že aserce se používá pro případ, že se vyskytne neočekávaný stav, při kterém je lepší program ukončit.

Zápis Assertion

Podívejme se konečně na to, jak zapisovat Assertion. Obecně lze říci, že je lze zapisovat dvěmi následujícími způsoby:

     Assert  (podmínka);
     Assert  (podmínka: 'text');

V podmínce můžete například hledat nepřijatelnou hodnotu např. nil. Assertion se provede pouze vyhodnotí-li se podmínka jako false. V nepovinném textu můžete napsat text, který chcete aby se vypisoval. Prakticky to může vypadat takto:

     Assert  (0 > myValue);
     Assert  (not  (firstName = ''));
     Assert  (not  (value = count));
     Assert  (myFunction(myParameter));

Resp. s textem takto:

     Assert  (0 > myValue: 'hodnota mimo rozsah');
     Assert  (not  (firstName = ''): 'Jméno nemůže být prázdné');
     Assert  (not  (value = count): 'hodnota musí být < než count');
     Assert  (myFunction(myParameter): 'function failed');

Z příkladu by mělo být zřejmé, že podmínka musí být typu boolean. Což samozřejmě znamená, že zde nemusí být jen podmínka, ale také např. návratová hodnota nějaké funkce.

Pro názorné pochopení bych mohl napsat, jak asi vypadá interpretovaný kód tohoto zápisu. Tím myslím pouze fakt, že většina příkazů, ať již v kterémkoliv jazyce se obvykle dá přepsat do nižší úrovně, dokud nedojdeme až k assembleru. Takže vezmeme-li klíčové slovo Assert, pak to neznamená nic jiného než zhruba toto:

     Assert  (podmínka: 'zpráva');
     
     // resp. =>
     
     if  (not  (podmínka)) then  begin 
          raise  EAssertionFailed.Create('zpráva');
     end  ;

Tento zápis však nemá ten komfort, že změnou jediné Compiler Directive mohu povolit či zakázat aserci. Více dále.

Z vlastnosti, že se vyhodí Assertion plyne jedna zřejmá vlastnost. To je možnost zachycení výjimky EAssertionFailed pomocí bloku try – except. Takže paradoxně lze ošetřit výjimku asi zcela odlišným způsobem než zamýšleli její tvůrci.

// soubor ExceptAF.dpr
program  ExceptAF;

{$APPTYPE CONSOLE}

uses  SysUtils, Dialogs;

var  str: String  ;
begin 
     str:= '';
// ...
     try 
          Assert  (not  (str = ''));
     except 
          on  EAssertionFailed do  MessageDlg('Nastalo Assertion', mtError, [mbOK], 0);
     end  ;
// ... still working
end  .

Z toho je asi názorně vidět, že ve vlastních procedurách či funkcích nemusíme mít deklarovány vlastní výjimky, ale často si vystačíme s tomto. Beru-li v úvahu takovou výjimku, která slouží pouze k interním účelům (občas se můžete setkat, že místo vlastní definice se použije již nějaká existující, často raise Exception.create(...);), tedy nepředává se nadřazené metodě apod.

Ještě lepším než jen zachycením s pozdějším ukončením programu je výjimku zpracovat o trochu jinak. Program pak není ukončen a běží dál — pouze vypisuje chybové kódy o Assertion. Tento výpis nemusí být nutně prováděn na obrazovku, ale např. do log souboru. Otázkou je zda je to vhodné v daném případě.

// soubor ExceptAF2.dpr
program  ExceptAF2;

{$APPTYPE CONSOLE}

uses  SysUtils, Dialogs;

var  str: String  ;
begin 
     str:= '';
// ...
     try 
          Assert  (not  (str = ''), 'Řetězec je prázdný');
     except 
          on  E: EAssertionFailed do  Writeln(Format('%s (HelpContext: %d)', [E.Message, E.HelpContext]));
     end  ;
// ... still working
     Readln;
end  .

Předchozí příklad svádí pro jiné řešení — klasicky přes výjimky. Věřte mi, že použití Assertion má jednu výhodu — zpráva obsahuje název souboru a řádek, kde nastalo. A právě toto může být velmi dobrá nápověda při analýze log souboru.

Kompilace

Defaultní hodnota Assertion je nastavena na ON – zapnutá. Samotné povolení či zakázání se provádí přes Compiler Directovies. Přesně přes C resp. ASSERTIONS. Nutno podotknout, že tato direktiva je lokální. Tj. lze ji zapínat či vypínat v jednotlivých částech programu — zapisuje se přímo do kódu, ve kterém má plnit svůj význam. V programu to vypadá takto:

// Povolení Assertion
{$C+}
// resp.
{$ASSERTIONS ON}

// Zakázání Assertion
{$C-}
// resp.
{$ASSERTIONS OFF}

Myslím si, že pro zasvěcení do Assertion v Delphi by to mohlo stačit. Zdrojové kódy zde zmíněných programů si můžete stáhnout v tomto souboru DelphiAssert.zip (1 kB).


1. – V manuálu asi naleznete 227, ale osobně si myslím, že se jedná o překlep. Protože program generuje 217.

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

Diskuse k článku

 

Vložit nový příspěvek   Sbalit příspěvky

 

Zatím nebyl uložen žádný příspěvek, buďte první.

 

 

Vložit nový příspěvek

Jméno:

Pohlaví:

,

E-mail:

Předmět:

Příspěvek:

 

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: