Bonjour à tous. Dans cette séquence, nous allons
présenter rapidement le débugger et la notion des
différents points d'arrêt disponibles en Pharo.
Ce que vous allez voir, c'est que le système est vivant
et on peut communiquer, et on doit communiquer avec lui, avec ces objets.
On ne travaille pas avec du code source, en fait, on
travaille avec des objets qui ont de l'état et à qui on
peut envoyer des messages qui vont nous répondre et caetera.
Il ne faut vraiment pas avoir peur d'utiliser le
débugger, on peut coder dans le débugger.
On peut inspecter le programme pendant qu'il tourne.
C'est vraiment un outil très puissant et vraiment très utile.
Je connais plusieurs développeurs et moi y compris qui
ont tendance à développer directement dans le débugger.
Donc, beaucoup beaucoup de codes est écrit dans le
débugger plutôt que dans un navigateur de codes.
Alors l'intérêt de ça, c'est qu'au moment où on écrit le
code on a accès aux paramètres des méthodes, on a accès
aux objets, on a accès aux variables, on peut regarder
tout ça, on peut essayer à ce moment-là.
On a toutes les données qui sont à portée de main pour
pouvoir être testées au moment où on écrit le code.
Donc le débugger se présente comme ça.
Une barre de titre qui indique le message d'erreur.
Ici la pile d'appel, c'est-à-dire la méthode qui appelle.
On voit que cette méthode performTest a appelé la méthode
testSumming, qui a appelée la méthode Plus qui
a levé ce problème de doesNotUnderstand.
Ici, on a le code de la zone qui est
sélectionnée ici, Donc là ce qui est sélectionnée, c'est
la méthode plus la classe de DiceHandle, donc ça apparaît
dans la zone du bas. Et tout en bas on a
différentes variables, toutes les variables qui sont
accessibles dans le contexte d'exécution en cours.
Donc, pour pouvoir modifier des variables pour pouvoir
inspecter les objets et caetera.
C'est un ensemble d'actions à cet endroit-là qui
permettent de relancer l'exécution de la méthode ou de
plonger à l'intérieur du code ou de regarder ligne à ligne, ce qui se passe.
Quand vous avez un debugger qui s'ouvre, le fermer ne
résoudra pas votre problème. Il est beaucoup plus facile
d'ouvrir le debugger à ce moment-là, de regarder à l'intérieur
en détail d'où vient les problèmes, d'inspecter un petit
peu la pile d'appel et les objets et de corriger le
problème directement dans le debugger, plutôt que de le
fermer et ensuite de deviner pourquoi un debugger a pu s'ouvrir à un moment.
Le debugger est vraiment votre meilleur ami.
Il permet de communiquer avec tous les objets du contexte.
Donc, ça soit les paramètres les variables d'instances et cetera.
De vérifier l'état de toutes les variables et même de modifier cet état-là.
D'envoyer des messages pour vérifier l'état de certains
objets ou pour vérifier comment ils réagissent.
On peut bien sûr modifier les méthodes qui sont sur la
pile d'exécution, sauvegarder et reprendre l'exécution
avec le nouveau code sans aucun problème.
Et tout ça sans redémarrer l'exécution depuis le début du programme.
Donc si une méthode plante, on corrige la méthode, on
relance l'exécution de la méthode et le programme continue à s'exécuter.
Une façon de debugger très fréquemment utilisée, c'est
d'afficher des choses sur la console.
Mais on voit que ça c'est vraiment
un moyen assez pauvre de debugger, parce que déjà il faut
modifier toutes les méthodes dans lesquelles on a envie d'avoir
des traces, et après il faudra les remodifier pour les
enlever une fois qu'on aura corrigé le problème.
Et puis il faut savoir, il faut avoir une idée un peu d'où
le problème pourrait se trouver et d'où est-ce qu'il
pourrait venir pour pouvoir savoir où mettre la ligne et pour afficher.
Une autre façon de faire ça, c'est d'utiliser la notion de point d'arrêt.
Donc un point d'arrêt c'est un endroit dans le code où on
va indiquer un Pharo qui doit s'arrêter la prochaine fois
qui passe à cet endroit-là. Donc le point d'arrêt le plus
simple, c'est Halt now, donc envoyer le message now à l'objet
halt qui est une classe, qui arrêtera l'exécution
immédiatement à ce moment-là et à partir de là, un
debuggeur va s'ouvrir et on pourra aller regarder ligne à
ligne ce qui se passe, regarder l'état du programme.
Donc halt now met en pause le programme.
On pourra toujours le relancer après, mais pour le
moment, il en pause et ouvre un debugger avec l'état
courant de l'application.
Donc halt now c'est très bien, sauf si vous mettez ça
dans une méthode qui est exécutée en permanence, y
compris par le système lui-même. Et vous pouvez avoir
des dizaines et des dizaines de debuggers qui s'ouvrent
si vous mettez un halt now à un endroit qui est utilisé
par un debuggeur qui s'ouvre.
Donc vous mettez Halt now dans le code du debuggeur, si
le debugger s'ouvre, il va lui-même exécuter Halt now qui
va ouvrir un autre debugger, et cetera, récursivement et
donc vous pouvez bloquer votre système comme ça.
Donc dans ces cas là on utilise HaltOnce, qui une fois
que le halt once est activé, il s'arrête une fois, il
bloque une fois et tous les passages suivants sur Halt
Once ne bloqueront pas l'exécution du programme.
Donc HaltOnce, on écrit ça n'importe où dans le code,
on l'active une fois, on exécute le programme, un
debugger s'ouvre et HaltOnce se désactive immédiatement.
Une autre possibilité, c'est de s'arrêter au bout d'un
certain nombre d'itérations. On peut décider de s'arrêter
au bout de la dixième itération, si on sait qu'un élément
dans une collection qui nous intéresse se trouve à la
dixième position, ce n'est pas forcément la peine de
debugger les 9 fois précédentes pour rien.
Donc, on s'arrête juste à la dixième itération.
Une autre possibilité, c'est de s'arrêter quand une
condition particulière est vraie.
Donc pour ça, on a Halt if.
Halt if prend soit un symbole qui indique une méthode qui
doit se trouver dans la pile d'appels pour que le
debuggeur s'ouvre, c'est-à-dire que là si je mets halt
if, printSpring, il faut que le code Dice faces ait été
appelé depuis la méthode printString, pour que le point d'arrêt
s'active et que le programme se mette en pause.
If peut prendre aussi un bloc et donc dans ce block, on
met n'importe quel bout de code dont la valeur doit être
vrai pour que le debugger s'arrête, et faux pour que le
debugger ne s'ouvre pas et que le programme continue.
Comme les tests en Pharo sont des méthodes qui sont dans
la pile d'appels, vous pouvez mettre le nom d'un test
pour qu'un bout code ne s'arrête que lorsqu'il est exécuté depuis un test.
Toutes ces méthodes now, once, account, if sont des
méthodes de la classe Halt.
Vous pouvez aller étudier le code, voir ce que ce code-là
fait et vous pouvez aussi ajouter vos propres méthodes,
donc ajouter vos propres types de breakpoint suivant vos besoins.
Donc là, dans l'exemple qui est en-dessous, j'ai codé un
breakpoint qui s'appelle between and et qui arrête le
programme seulement lorsqu'
il est entre minTime et maxTime.
Donc là, ici ce programme qui est là, le debugger s'ouvrira
seulement entre minuit et 2 heures du matin.
Ce que vous devez retenir c'est que le debugger est un
outil extrêmement puissant. Il y a beaucoup de
breakpoints, donc de points d'arrêt qui sont définis déjà
dans le système, vous pouvez en ajouter autant que vous voulez.
Pour mettre un breakpoint vous modifiez une méthode, le
debugger s'ouvre, et vous pouvez aller regarder ligne à
ligne, ce qui se passe.
Les points d'arrêt sont vraiment puissants et il faut
surtout ne pas hésiter à l'utiliser tout comme le debugger.