Ecrire des classes fiables (Assertions et débogage)

Formation écrire des classes fiables, tutoriel & guide de travaux pratiques en pdf.

Erreurs de compilation

L’erreur la plus courante et la plus simple à corriger est celle qui apparaît lors de la compilation. Le  compilateur indique alors le type d’erreur et la ligne où celui­-ci a trouvé un problème. Dans la  majorité des cas, il s’agit
✔ d’erreurs typographiques.
✔ d’oublis de déclaration de variables.
✔ d’appels de méthodes non existantes.
✔ de non respect des types et/ou du nombre d’arguments lors de l’utilisation de méthodes. Dans la majorité des cas, le compilateur est très dithyrambique dans ses commentaires et est d’une  aide précieuse. 2. Erreurs lors de l’exécution du programme

Arrêt du programme à l’exécution

Cette fois, la compilation se déroule sans erreur mais à l’exécution, le programme « plante ». L’erreur  la plus courante est l’oubli de la création d’un objet qui se traduit par le message suivant: *** Error at Run Time ***: Call with a Void target.
Il est assez facile de corriger le bogue en consultant l’état de l’objet au moment du « plantage ». 2 frames in current stack. =====  Bottom of run­time stack  ===== <system root> Current = TST#0x8775038         [ str = Void         ] line 7 column 2 file /home/jct/bioinfo/work/tst.e ====================================== make TST Current = TST#0x8775038         [ str = Void         ] line 9 column 8 file /home/jct/bioinfo/work/tst.e =====   Top of run­time stack    ===== Line : 9 column 4 in /home/jct/bioinfo/work/tst.e. *** Error at Run Time ***: Call with a Void target.
Dans le message précédent, on peut lire qu’il y a eu une utilisation d’un objet Void dans la ligne 9.  L’objet en question str est à l’état Void; donc il est l’auteur du « plantage ». Current = TST#0x8775038         [ str = Void         ]

Comportement instable du programme

Une fois passé ce stade, il reste les erreurs qui ne font pas « planter » le programme mais qui ne donne  pas le résultat escompté. Il faut alors s’assurer que les objets ont un « comportement » normal  correspondant aux attentes du créateur de classes.  Les erreurs peuvent survenir à deux niveaux:
✔ au niveau du programmeur « client » qui utilise incorrectement les classes.
✔ au niveau de l’utilisateur qui n’utilise pas le programme de façon correcte.

Assertions: Garde-fous pour le programmeur client

Une assertion est un test qui s’il est incorrect déclenche l’arrêt de l’exécution du programme. Il joue  le rôle d’une sorte de filtre – placé dans une routine ou une classe – qui va bloquer et arrêter  l’exécution du programme s’il y a eu une utilisation anormale.
ATTENTION!!! L’assertion ne sert que pendant la phase de test de classes ou du  programme et sera « enlevée » une fois que le programme est en phase de production.  Il est donc impératif que l’assertion n’ait aucun rôle dans le comportement d’une  classe ou d’un programme.
La syntaxe est la suivante: Il est d’usage d’associer au test de l’assertion, un message qui sera affiché par le programme au moment de l’arrêt du programme. La syntaxe d’une assertion en Eiffel est la  suivante: my_tag_explaining_the_assertion : condition L’étiquette my_tag_explaining_the_assertion est un seul mot (on utilise donc souvent le caractère  souligné « _ » pour faire une mini­phrase résumant la condition de l’assertion. L’assertion est  équivalente au pseudo­code suivant: if condition = False then io.put_string(« my_tag_explaining_the_assertion%N ») die_with(1)  ­­ End of program end
Une assertion classique est de vérifier que l’argument de votre routine est non vide. Par exemple,  pour une méthode foo(arg : MY_CLASS) l’assertion peut alors ressembler à: arg_not_void : arg /= Void

LIRE AUSSI :  Histoire et définitions de l’internet

Assertions au niveau des routines

Les routines en Eiffel peuvent être réglementées par des pré­ et des post­ conditions qui sont des  assertions placées respectivement dans les blocs require et ensure. Une routine classique peut donc  être organisée de la manière suivante: foo(arg1 : INTEGER; arg2 : MY_CLASS) is require ­­ Here are the pre­conditions (first assertion block) local ­­ Declaration of local variables do ­­ code ensure ­­ Here are the post ­conditions (last assertion block) end
Le programmeur « client » doit utiliser la routine foo en respectant les clauses d’un « contrat » entre  lui et le créateur de classes via la routine foo. Si les clauses du contrat sont respectées (les preconditions et les post­conditions sont correctes), alors la routine est exécutée. Dans le cas contraire,  le contrat est rompu, l’exécution s’arrête. Ce schéma de fonctionnement est nommé par le fondateur  du langage Eiffel Bertrand Meyer, le « design by contract ».
L’exemple typique est l’utilisation de la méthode sqrt qui calcule la racine carrée d’un nombre. La  ligne suivante est incorrecte: (­1).sqrt ­­ Nombre négatif interdit
class TST
creation make
feature make is do
io.put_double( (­1).sqrt); io.put_new_line
end end ­­ end of class TST
A l’exécution du programme, le message suivant est affiché: *** Error at Run Time ***: Require Assertion Violated. 3 frames in current stack. =====  Bottom of run­time stack  ===== <system root> Current = TST#0x9241038 line 7 column 2 file /home/jct/bioinfo/work/tst.e  ====================================== make TST Current = TST#0x9241038 line 9 column 7 file /home/jct/bioinfo/work/tst.e  ====================================== sqrt INTEGER_8 Current = ­1 Result = 0.000000
line 238 column 9 file  /usr/local/SmartEiffel/lib/numeric/integer_general.e  =====   Top of run­time stack    ===== *** Error at Run Time ***: Require Assertion Violated.

Cours gratuitTélécharger le cours complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *