WEBVTT

00:00:00.670 --> 00:00:01.430 align:middle
Bonjour à tous.

00:00:01.850 --> 00:00:03.850 align:middle
Aujourd'hui, nous allons
parler des erreurs qui sont

00:00:04.050 --> 00:00:07.190 align:middle
fréquemment commises par les
développeurs Pharo, y compris moi-même.

00:00:08.570 --> 00:00:10.690 align:middle
Nous allons essayer de voir
comment on peut repérer ces

00:00:10.890 --> 00:00:12.370 align:middle
erreurs facilement et
les corriger rapidement.

00:00:13.830 --> 00:00:17.270 align:middle
Ici, nous avons un bout
de code qui, quand il est

00:00:17.470 --> 00:00:22.070 align:middle
exécuté, un débugger
s'ouvre et nous dit

00:00:22.270 --> 00:00:25.490 align:middle
que le message self a été
envoyé à un objet, et que cet

00:00:25.690 --> 00:00:27.070 align:middle
objet ne comprend
pas le message self.

00:00:27.270 --> 00:00:30.540 align:middle
On peut se dire, self, en
général, ce n'est pas trop un

00:00:30.740 --> 00:00:34.350 align:middle
message qu'on envoie, il y a
donc probablement une erreur

00:00:34.550 --> 00:00:35.580 align:middle
quelque part dans le code.

00:00:36.420 --> 00:00:41.210 align:middle
En regardant un peu, on
voit qu'ici il manque un

00:00:41.410 --> 00:00:45.280 align:middle
point et
l'exécution se passe comme si

00:00:46.070 --> 00:00:49.380 align:middle
self était un message qui était
envoyé au résultat de DiceHandle new.

00:00:50.730 --> 00:00:54.560 align:middle
Comme la classe DiceHandle
n'a pas de méthode self, on a

00:00:54.760 --> 00:00:57.810 align:middle
ce débugger qui s'ouvre.

00:00:58.010 --> 00:01:01.240 align:middle
La solution c'est
d'ajouter ce point à la fin de la

00:01:01.440 --> 00:01:04.000 align:middle
première ligne.

00:01:04.160 --> 00:01:07.170 align:middle
Un autre problème qu'on
obtient régulièrement, ce sont

00:01:07.550 --> 00:01:10.920 align:middle
des messages qui a priori ne
devraient pas être combinés

00:01:11.120 --> 00:01:14.290 align:middle
et qui sont combinés. Là,
on a une erreur qui nous

00:01:14.490 --> 00:01:16.800 align:middle
indique que include if true
n'existe pas, include existe,

00:01:17.000 --> 00:01:19.460 align:middle
if true existe,
include if true n'existe pas.

00:01:19.700 --> 00:01:23.430 align:middle
En regardant de plus près,
on se rend compte ici que

00:01:23.820 --> 00:01:26.940 align:middle
effectivement on envoie le
message include ifTrue au

00:01:27.870 --> 00:01:31.080 align:middle
receveur X avec deux
paramètres, 33 et un block.

00:01:32.420 --> 00:01:36.330 align:middle
Ça ne marche pas. Pharo ce
qu'il fait quand il voit un

00:01:36.530 --> 00:01:38.840 align:middle
mot-clé, il essaye de
regarder tous les mots-clés qui

00:01:39.040 --> 00:01:40.720 align:middle
suivent, il les prend tous,
il considère que ça c'est un

00:01:40.920 --> 00:01:44.940 align:middle
seul envoi de message. Ce
qui manque ici, c'est une paire

00:01:45.140 --> 00:01:47.930 align:middle
de parenthèses pour dire que
le message ifTrue envoie au

00:01:48.130 --> 00:01:49.420 align:middle
résultat de X include 33.

00:01:50.590 --> 00:01:54.860 align:middle
De la même façon, assert
include n'existe pas, ce qu'on a

00:01:55.060 --> 00:01:58.110 align:middle
voulu faire c'est assert
sur le résultat d'include, et

00:01:58.310 --> 00:02:01.380 align:middle
donc il manque des parenthèses ici.

00:02:02.110 --> 00:02:05.350 align:middle
Il ne faut pas hésiter à
mettre des parenthèses quand on

00:02:05.550 --> 00:02:08.210 align:middle
a plusieurs messages à
mots-clés dans la même expression,

00:02:09.510 --> 00:02:11.930 align:middle
pour bien les séparer car
Pharo va essayer de regrouper

00:02:12.130 --> 00:02:16.000 align:middle
tous les mots-clés ensemble. et il
considère que c'est un seul message.

00:02:17.190 --> 00:02:21.060 align:middle
Dans cet exemple-ci, on
souhaiterait dans la variable

00:02:21.260 --> 00:02:24.370 align:middle
numbers avoir une
collection de nombres, et pour le

00:02:24.570 --> 00:02:26.550 align:middle
moment cette collection ne
contient qu'un seul nombre, le nombre 35.

00:02:26.750 --> 00:02:31.000 align:middle
Cependant, si on regarde ce
qui est dans numbers, ce n'est

00:02:31.200 --> 00:02:33.560 align:middle
pas une collection,
c'est le nombre 35.

00:02:33.760 --> 00:02:35.530 align:middle
Il y a donc un problème.

00:02:37.400 --> 00:02:42.000 align:middle
De la même façon, sur ce code-là, si

00:02:42.690 --> 00:02:46.100 align:middle
j'envoie le message new à
la classe dice, j'obtiens le

00:02:46.300 --> 00:02:48.950 align:middle
nombre 6 plutôt qu'un dé à 6 faces.

00:02:49.710 --> 00:02:52.010 align:middle
En fait, c'est le même
problème dans les 2 exemples.

00:02:52.400 --> 00:02:55.830 align:middle
Si on regarde plus
précisément, le fait d'envoyer

00:02:56.030 --> 00:02:59.070 align:middle
yourself après add, va
corriger le problème.

00:02:59.270 --> 00:03:02.110 align:middle
Pourquoi? Parce que add
retourne son paramètre.

00:03:03.140 --> 00:03:07.490 align:middle
Et donc,
OrderedCollection new add 35, retourne 35.

00:03:08.120 --> 00:03:10.900 align:middle
Si on ajoute la cascade et
yourself, on s'assure d'obtenir

00:03:11.100 --> 00:03:14.110 align:middle
le receveur à la fin et numbers
est bien une collection de nombre.

00:03:14.920 --> 00:03:19.230 align:middle
Donc les solutions ici,
c'est bien d'ajouter yourself à

00:03:19.430 --> 00:03:20.780 align:middle
la fin de chaque envoi de message.

00:03:21.770 --> 00:03:22.660 align:middle
Voici un autre problème.

00:03:23.310 --> 00:03:28.260 align:middle
On a une classe book, une
méthode borrow, et quand on l'exécute

00:03:28.460 --> 00:03:31.450 align:middle
on obtient le message que
nil ne comprend pas ifFalse.

00:03:32.500 --> 00:03:37.390 align:middle
On envoie le message ifFalse
ici à nil, ça veut dire que

00:03:37.590 --> 00:03:40.180 align:middle
in library à la valeur nil
qui est la valeur par défaut

00:03:40.380 --> 00:03:43.420 align:middle
pour toutes les variables,
ce qu'on peut se dire c'est

00:03:43.620 --> 00:03:45.430 align:middle
que probablement in
libray n'a jamais initialisé.

00:03:46.580 --> 00:03:50.740 align:middle
Donc il faut donc mettre une valeur
par défaut dans cette variable-là.

00:03:51.890 --> 00:03:54.910 align:middle
On peut corriger ça assez
facilement, en ajoutant une

00:03:55.110 --> 00:03:59.730 align:middle
méthode initialize qui dès
la création de l'instance de

00:04:00.290 --> 00:04:03.830 align:middle
chaque instance de la
 classe book, va mettre la valeur

00:04:04.030 --> 00:04:07.300 align:middle
true dans la variable
d'instance in library.

00:04:07.720 --> 00:04:10.430 align:middle
Sauf que si on exécute ce
code-là maintenant, on va avoir

00:04:10.630 --> 00:04:14.720 align:middle
un autre message d'erreur
qui est class true ne comprend

00:04:14.920 --> 00:04:15.690 align:middle
pas le message ifFalse.

00:04:15.890 --> 00:04:18.640 align:middle
D'où est-ce que ça vient ?

00:04:19.420 --> 00:04:23.720 align:middle
Ce qu'on a mis ici c'est
une classe, ce n'est pas un

00:04:23.920 --> 00:04:25.050 align:middle
booléen c'est une classe.

00:04:26.130 --> 00:04:29.170 align:middle
Le booléen c'est true
avec un T minuscule.

00:04:30.570 --> 00:04:34.010 align:middle
Les classes prennent en
général une majuscule.

00:04:35.020 --> 00:04:38.000 align:middle
Et donc true avec un T
majuscule c'est une classe et true

00:04:38.200 --> 00:04:41.040 align:middle
avec un T minuscule, c'est la
seule instance de la classe true.

00:04:42.060 --> 00:04:43.850 align:middle
Voici un autre problème.

00:04:44.310 --> 00:04:46.430 align:middle
On a une méthode roll dans
une classe dice, on s'attend à

00:04:46.630 --> 00:04:49.640 align:middle
ce que quand on fait rouler
un dé, on obtienne un nombre

00:04:50.000 --> 00:04:53.470 align:middle
entre 1 et le nombre de
faces du dé, sauf que là, quand

00:04:53.670 --> 00:04:57.530 align:middle
on fait rouler le dé,
on obtient un dé et pas

00:04:58.720 --> 00:05:00.010 align:middle
la face sur laquelle on est tombé.

00:05:01.490 --> 00:05:04.270 align:middle
La méthode que je viens de
vous montrer est équivalente à

00:05:04.470 --> 00:05:08.100 align:middle
la méthode ci-dessous,
c'est-à-dire que, par défaut, une

00:05:08.300 --> 00:05:10.500 align:middle
méthode qui ne
renvoie rien renvoie self.

00:05:11.660 --> 00:05:14.430 align:middle
C'est-à-dire que notre méthode
roll, quand elle va s'exécuter,

00:05:14.630 --> 00:05:17.650 align:middle
elle va retourner le dé et
non pas le résultat d'envoyer

00:05:17.850 --> 00:05:21.690 align:middle
at random à

00:05:23.000 --> 00:05:23.750 align:middle
la collection faces.

00:05:25.040 --> 00:05:27.440 align:middle
Donc le même problème dans un
exemple un petit peu différent.

00:05:28.080 --> 00:05:32.570 align:middle
Ici on crée une méthode
new dans la classe dice,

00:05:33.650 --> 00:05:36.250 align:middle
donc dans dice class ce
qu'on veut c'est faire une

00:05:36.450 --> 00:05:38.920 align:middle
nouvelle méthode pour créer
des instances de la classe

00:05:39.120 --> 00:05:42.860 align:middle
dice qui initialise, par
défaut, le nombre de face à zéro.

00:05:44.190 --> 00:05:47.320 align:middle
Si on envoie le message new
à la classe dice, ce qu'on va

00:05:47.520 --> 00:05:50.460 align:middle
obtenir c'est la classe
dice elle-même plutôt qu'une

00:05:50.660 --> 00:05:51.540 align:middle
nouvelle instance de la classe dice.

00:05:53.330 --> 00:05:56.950 align:middle
Dans les 2 cas, le fait
qu'il n'y ait pas de return self

00:05:57.150 --> 00:05:59.470 align:middle
et self, par
défaut, c'est le receveur.

00:05:59.670 --> 00:06:02.690 align:middle
Donc dans le cas d'une méthode
de classe, self c'est la classe.

00:06:03.440 --> 00:06:07.110 align:middle
Pour corriger ces 2
problèmes, il suffit d'ajouter le

00:06:07.310 --> 00:06:09.310 align:middle
chapeau pour retourner une
valeur bien particulière.

00:06:11.250 --> 00:06:16.030 align:middle
Problème suivant. Si ce
code-là est exécuté, le

00:06:16.230 --> 00:06:20.900 align:middle
système semble être bloqué,
il ne se passe plus rien et

00:06:21.100 --> 00:06:22.780 align:middle
impossible d'interagir avec Pharo.

00:06:24.170 --> 00:06:25.110 align:middle
D'où vient ce problème ?

00:06:25.540 --> 00:06:28.500 align:middle
Le problème vient du fait
qu'on est en train d'implémenter

00:06:28.700 --> 00:06:30.040 align:middle
une méthode new dans dice classe.

00:06:30.330 --> 00:06:33.720 align:middle
Self c'est Dice,

00:06:36.520 --> 00:06:39.870 align:middle
et donc self new va se
rappeler récursivement.

00:06:41.380 --> 00:06:44.790 align:middle
Ce qu'on a voulu faire ici,
c'est utiliser l'initialisation,

00:06:45.000 --> 00:06:47.740 align:middle
la création d'instance par
défaut définie dans la super

00:06:47.940 --> 00:06:50.700 align:middle
 classe de Dice, et ensuite
ajouter des choses par rapport à ça.

00:06:51.650 --> 00:06:53.600 align:middle
En l'écrivant comme ça,
on a une boucle infinie.

00:06:54.910 --> 00:06:59.520 align:middle
Il faut remplacer self par
super pour demander l'implémentation

00:07:00.870 --> 00:07:01.630 align:middle
de la super-classe.

00:07:03.070 --> 00:07:04.730 align:middle
Ce que vous devez retenir.

00:07:06.520 --> 00:07:08.650 align:middle
Donc on commet tous
beaucoup d'erreurs.

00:07:08.850 --> 00:07:10.470 align:middle
Les erreurs que je vous ai
présentées sont des erreurs

00:07:10.670 --> 00:07:13.500 align:middle
très, très fréquemment commises
par tous les développeurs Pharo.

00:07:14.340 --> 00:07:17.310 align:middle
Il y a des choses qu'on
retrouvent très régulièrement:

00:07:18.170 --> 00:07:23.000 align:middle
les points qui
manquent, les parenthèses, le

00:07:23.200 --> 00:07:25.540 align:middle
chapeau qui manque ou yourself.

00:07:27.060 --> 00:07:30.490 align:middle
Essayez d'utiliser un maximum le
débugger pour trouver l'origine

00:07:30.690 --> 00:07:32.640 align:middle
du problème. Vous verrez
que le débugger vous aide

00:07:32.840 --> 00:07:35.820 align:middle
vraiment et qu'il ne vaut
mieux pas le fermer dès qu'il

00:07:36.020 --> 00:07:39.200 align:middle
s'ouvre, parce que vous loupez
une façon de corriger les problèmes.

