Appendice D — Mise au point (Débogage)
Si vous écrivez des programmes, vous écrirez des erreurs (des
bugs,
aussi appelés « bogues » en français). Ne vous sentez pas coupable ; voyez
simplement combien de « service packs » et combien de mises à jour en ligne
chaque version de
Windows™
finit par amener. Les programmeurs professionnels écrivent des bugs
professionnels ! Si vous utilisez une méthode de conception correcte, vous éliminerez une grande
partie du stress provoqué par la recherche des bugs. En découpant votre programme en morceaux, chacun
avec une tâche bien définie, vous pourrez vérifier chaque
PROC
et chaque
FN
séparément pour vous assurer qu'elle fait bien le travail qui lui est dévolu, avant de l'incorporer
dans le programme principal.
Idéalement, vous devriez tester chaque routine avec toutes les combinaisons de variables possibles ;
ceci est particulièrement vrai quand vous demandez aux utilisateurs d'entrer une information.
Il ne sert pas à grand chose de vous tourner vers la personne qui vient de faire
« planter » votre chef-d'œuvre bien-aimé pour vous écrier, rempli de
frustration :
— Mais dis donc ! Pourquoi tu as appuyé sur cette touche ?
Votre programme devrait être capable de tenir compte des entrées valides et
invalides.
Une des choses qui sépare les bons programmeurs des programmeurs indifférents, c'est leur capacité
à rechercher les bugs dans le code et à les détruire. (Votre capacité d'admettre que vous vous trompez
parfois n'est pas non plus à négliger !). En gros, cette habileté s'acquiert par l'expérience et
par la franche obstination : « Ce n'est qu'une machine, je ne vais pas la laisser me
battre ! ». Il existe plusieurs techniques pour vous aider ici. Dans cette section,
nous en couvrirons quelques-unes. Veuillez garder à l'esprit que la liste n'est pas exhaustive.
Chaque bug a une solution légèrement différente et parfois vous devrez simplement inventer vos propres
méthodes.
Cette discussion ignorera totalement les erreurs de syntaxe qui se produisent lorsque vous faites
une faute d'orthographe sur le nom d'une variable ou sur un mot-clé ; alors, le
BASIC
se plaint avec « Mistake at line 1230 » (Faute à la ligne 1230).
Ce sur quoi nous voulons nous concentrer, c'est le moment où le programme tourne assez bien mais,
tout simplement, ne se comporte pas exactement comme nous le voudrions.
Le premier outil de notre arsenal, c'est notre vieil ami
PRINT.
Vous ne comprenez pas pourquoi votre boucle
WHILE
ne finit jamais ? Mettez un
PRINT
dans la boucle avec les variables qui régissent la condition de sortie et observez les résultats
qui défilent vers le haut de l'écran. Il arrive que trop de
PRINT
gâchent l'affichage sur l'écran, ou que les données changent trop vite pour pouvoir les voir.
Dans les deux cas, vous pouvez utiliser
PRINT
TAB
pour afficher les résultats dans un endroit commode, puis mettre une ligne d'entrée factice qui arrête
le programme pour vous donner le contrôle du moment où les données changent.
REM Boucle d'attente
FOR I%=1 TO 10
REM les espaces de fin
REM remplacent les données écrites
PRINT TAB(0,24);I%;" "
Factice$=GET$
NEXT I%
END
La ligne 5 attend simplement qu'on appuie sur une touche sans utiliser le résultat, arrêtant ainsi la boucle. On peut insérer une condition afin d'économiser les entrées au clavier et le temps.
REM Arrêt d'une boucle
FOR I%=1 TO 10
IF I%>5 AND I%<8 THEN
PRINT TAB(0,24);I%;" "
Factice$=GET$
ENDIF
NEXT I%
END
L'autre commande qui peut être insérée dans notre code est
TRACE.
TRACE s'utilise avec ON et OFF. Quand le
BASIC rencontre
TRACE ON,
il affiche entre crochets chaque numéro de ligne jusqu'à ce qu'il rencontre
TRACE OFF
ou bien que le programme s'arrête. Évidemment, il vous faut un programme avec des lignes numérotées
pour faire ceci. Ne vous rendez pas esclave de l'affichage que le programme est censé faire, parce que là,
il se peut que l'affichage des numéros de lignes se fasse en une fraction de seconde. Cette commande est
plus utile quand vous voulez suivre le chemin que le programme prend pour une série de variables donnée.
10 REM Suivre un programme à la TRACE
20 TRACE ON
30 FOR I%=1 TO 10
40 PRINT TAB(0,24);I%;" "
50 NEXT I%
60 TRACE OFF
70 END
TRACE
n'affichera le numéro de ligne que lorsque la ligne est exécutée pour la première fois. Si vous avez
une boucle dans une ligne comme ceci :
120 REPEAT : UNTIL INKEY$(0)
la ligne ne se montrera qu'une seule fois dans la trace malgré le fait que le
BASIC
est en train de faire obstinément le tour de la boucle en attendant qu'on appuie sur une touche.
TRACE
acceptera aussi un numéro de ligne comme paramètre. L'idée, c'est qu'il n'affichera que les numéros
de lignes inférieurs à celui qui est spécifié. Si vous écrivez les programmes de la façon décrite
dans la section finale de ce Guide pratique, toutes les
PROC
et toutes les
FN
sont placées après
END,
aussi, en utilisant le numéro de ligne de l'instruction
END,
vous aurez une vue de la structure d'ensemble du programme.
Je ne donne pas d'exemples trop nombreux ici, parce que l'éditeur de
BBC BASIC
possède un excellent outil de mise au point (débogage) qui éclipse les méthodes sus-mentionnées.
Il est parfois utile d'avoir quelques trucs sous le coude, même si ce n'est que pour l'inspiration, et
les deux qui précèdent existent depuis que
BBC BASIC
a été écrit pour la première fois.
Comme vous devez en être conscient, il est possible de voir l'éditeur pendant qu'un programme tourne.
Allez dans la barre de tâches de
Windows™
au bas de l'écran et le voici : il arrive d'un simple clic. Nous ne pouvons pas modifier le code pendant
l'exécution, mais le menu a toujours des options qui sont disponibles pendant le fonctionnement du programme.
Dans le menu Utilities, sélectionnez List Variables. Ceci ouvre une nouvelle fenêtre qui contient
une liste de toutes les variables utilisées au moment présent, ainsi que leur valeur actuelle. En sachant cela,
vous pouvez observer un programme en train de tourner sans insérer des instructions
PRINT.
C'est très utile.
La fenêtre peut être redimensionnée ou on peut la faire défiler comme on veut. Les variables
LOCAL
s'ajoutent aussi à la liste lorsque le programme entre dans une
PROC
ou une
FN,
ainsi que le nom de la
PROC
ou de la
FN,
de telle sorte que vous voyez où vous êtes. Si vous avez des noms en double, par exemple deux
PROC
qui ont des variables locales avec le même nom, le nom n'apparaît qu'une fois dans la liste même si en fait
il y a deux variables véritables en mémoire. La liste montre simplement la variable qui est visible
(« in scope ») à ce moment-là.
Il y a plusieurs boutons dans le même bloc, comme le bouton
Mode direct (immédiat).
Vous avez probablement utilisé le bouton
Run
(grande flèche noire) et peut-être le bouton
Stop
(carré noir). Nous allons maintenant voir les deux autres, mais auparavant, pourquoi pas un programme
pour expérimenter ?
REM Mise au point (debug) démonstration
FOR I%=1 TO 10
PRINT I%
PROC_Houla
NEXT I%
END
DEF PROC_Houla
LOCAL I
I%=10
ENDPROC
Voici un bug banal. Quand la PROC_Houla tourne, elle déclare une variable locale I,
mais elle met la globale I% à 10, d'où la fin de la boucle après une seule itération.
Nous allons maintenant utiliser le débogage pour détecter cette faute.
Tout d'abord, mettons en service l'option de Trace dans le menu Utilities en cliquant dessus.
C'est différent de la commande
TRACE
décrite un peu plus tôt. Quand notre programme est lancé, la ligne qui est exécutée est affichée sur
un fond noir dans l'éditeur. Essayez-le. La fenêtre
Mode direct (immédiat)
s'ouvre et dans l'éditeur la ligne
END
est affichée sur fond noir. Comme le programme tourne plus vite que ce que nous pouvons voir, ça ne sert pas
à grand chose. Le spectacle est terminé avant que vous n'ayez le temps de cligner des yeux.
Il existe une autre option pour nous permettre de suivre le programme, une ligne à la fois.
Pour démontrer ceci, mettez le curseur de l'éditeur sur la ligne 3, qui contient l'instruction
PRINT ; peu importe à quel endroit.
Cette fois, au lieu de presser la touche
Run,
choisissez le menu « Run » et cliquez sur « Run to cursor » (Exécuter
jusqu'au curseur). Le bouton de
Pause
sur la barre d'outils est affiché comme enfoncé et le bouton « Pas à pas »
est activé. Chaque fois qu'on appuiera sur ce bouton, le programme avancera jusqu'à la ligne suivante
et attendra. En avançant, un pas après l'autre, nous pouvons vérifier que la boucle n'est exécutée qu'une
seule fois. Faites ceci, et remarquez que le bouton
Pause
disparaît lorsque le programme se termine.
Remettez le curseur sur la ligne 3. Choisissez « Run to cursor » et
quand la pause devient active, ouvrez la liste des variables. Avancez de nouveau pas à pas. Quand le programme
arrive à PROC_Houla il crée une variable locale nommée I : vous la voyez apparaître dans
la liste. Continuez pas à pas dans la PROC_Houla : nous voyons que I% change de valeur,
et pas I comme on s'y attendait. À ce moment, la cause du bug nous frappe, aussi est-il
superflu de continuer à avancer pas à pas. En cliquant sur
Pause,
le bouton Pas à pas est relâché, ce qui permet au programme de se terminer à la vitesse
normale. Nous pouvons maintenant corriger notre petit bug, nous sentir vraiment satisfait de nous-même
et puis, nous flageller mentalement pour avoir commencé par le placer là.
Fin de l'Appendice D
|