1
00:00:00,670 --> 00:00:01,430
Bonjour à tous.

2
00:00:01,850 --> 00:00:03,850
Aujourd'hui, nous allons
parler des erreurs qui sont

3
00:00:04,050 --> 00:00:07,190
fréquemment commises par les
développeurs Pharo, y compris moi-même.

4
00:00:08,570 --> 00:00:10,690
Nous allons essayer de voir
comment on peut repérer ces

5
00:00:10,890 --> 00:00:12,370
erreurs facilement et
les corriger rapidement.

6
00:00:13,830 --> 00:00:17,270
Ici, nous avons un bout
de code qui, quand il est

7
00:00:17,470 --> 00:00:22,070
exécuté, un débugger
s'ouvre et nous dit

8
00:00:22,270 --> 00:00:25,490
que le message self a été
envoyé à un objet, et que cet

9
00:00:25,690 --> 00:00:27,070
objet ne comprend
pas le message self.

10
00:00:27,270 --> 00:00:30,540
On peut se dire, self, en
général, ce n'est pas trop un

11
00:00:30,740 --> 00:00:34,350
message qu'on envoie, il y a
donc probablement une erreur

12
00:00:34,550 --> 00:00:35,580
quelque part dans le code.

13
00:00:36,420 --> 00:00:41,210
En regardant un peu, on
voit qu'ici il manque un

14
00:00:41,410 --> 00:00:45,280
point et
l'exécution se passe comme si

15
00:00:46,070 --> 00:00:49,380
self était un message qui était
envoyé au résultat de DiceHandle new.

16
00:00:50,730 --> 00:00:54,560
Comme la classe DiceHandle
n'a pas de méthode self, on a

17
00:00:54,760 --> 00:00:57,810
ce débugger qui s'ouvre.

18
00:00:58,010 --> 00:01:01,240
La solution c'est
d'ajouter ce point à la fin de la

19
00:01:01,440 --> 00:01:04,000
première ligne.

20
00:01:04,160 --> 00:01:07,170
Un autre problème qu'on
obtient régulièrement, ce sont

21
00:01:07,550 --> 00:01:10,920
des messages qui a priori ne
devraient pas être combinés

22
00:01:11,120 --> 00:01:14,290
et qui sont combinés. Là,
on a une erreur qui nous

23
00:01:14,490 --> 00:01:16,800
indique que include if true
n'existe pas, include existe,

24
00:01:17,000 --> 00:01:19,460
if true existe,
include if true n'existe pas.

25
00:01:19,700 --> 00:01:23,430
En regardant de plus près,
on se rend compte ici que

26
00:01:23,820 --> 00:01:26,940
effectivement on envoie le
message include ifTrue au

27
00:01:27,870 --> 00:01:31,080
receveur X avec deux
paramètres, 33 et un block.

28
00:01:32,420 --> 00:01:36,330
Ça ne marche pas. Pharo ce
qu'il fait quand il voit un

29
00:01:36,530 --> 00:01:38,840
mot-clé, il essaye de
regarder tous les mots-clés qui

30
00:01:39,040 --> 00:01:40,720
suivent, il les prend tous,
il considère que ça c'est un

31
00:01:40,920 --> 00:01:44,940
seul envoi de message. Ce
qui manque ici, c'est une paire

32
00:01:45,140 --> 00:01:47,930
de parenthèses pour dire que
le message ifTrue envoie au

33
00:01:48,130 --> 00:01:49,420
résultat de X include 33.

34
00:01:50,590 --> 00:01:54,860
De la même façon, assert
include n'existe pas, ce qu'on a

35
00:01:55,060 --> 00:01:58,110
voulu faire c'est assert
sur le résultat d'include, et

36
00:01:58,310 --> 00:02:01,380
donc il manque des parenthèses ici.

37
00:02:02,110 --> 00:02:05,350
Il ne faut pas hésiter à
mettre des parenthèses quand on

38
00:02:05,550 --> 00:02:08,210
a plusieurs messages à
mots-clés dans la même expression,

39
00:02:09,510 --> 00:02:11,930
pour bien les séparer car
Pharo va essayer de regrouper

40
00:02:12,130 --> 00:02:16,000
tous les mots-clés ensemble. et il
considère que c'est un seul message.

41
00:02:17,190 --> 00:02:21,060
Dans cet exemple-ci, on
souhaiterait dans la variable

42
00:02:21,260 --> 00:02:24,370
numbers avoir une
collection de nombres, et pour le

43
00:02:24,570 --> 00:02:26,550
moment cette collection ne
contient qu'un seul nombre, le nombre 35.

44
00:02:26,750 --> 00:02:31,000
Cependant, si on regarde ce
qui est dans numbers, ce n'est

45
00:02:31,200 --> 00:02:33,560
pas une collection,
c'est le nombre 35.

46
00:02:33,760 --> 00:02:35,530
Il y a donc un problème.

47
00:02:37,400 --> 00:02:42,000
De la même façon, sur ce code-là, si

48
00:02:42,690 --> 00:02:46,100
j'envoie le message new à
la classe dice, j'obtiens le

49
00:02:46,300 --> 00:02:48,950
nombre 6 plutôt qu'un dé à 6 faces.

50
00:02:49,710 --> 00:02:52,010
En fait, c'est le même
problème dans les 2 exemples.

51
00:02:52,400 --> 00:02:55,830
Si on regarde plus
précisément, le fait d'envoyer

52
00:02:56,030 --> 00:02:59,070
yourself après add, va
corriger le problème.

53
00:02:59,270 --> 00:03:02,110
Pourquoi? Parce que add
retourne son paramètre.

54
00:03:03,140 --> 00:03:07,490
Et donc,
OrderedCollection new add 35, retourne 35.

55
00:03:08,120 --> 00:03:10,900
Si on ajoute la cascade et
yourself, on s'assure d'obtenir

56
00:03:11,100 --> 00:03:14,110
le receveur à la fin et numbers
est bien une collection de nombre.

57
00:03:14,920 --> 00:03:19,230
Donc les solutions ici,
c'est bien d'ajouter yourself à

58
00:03:19,430 --> 00:03:20,780
la fin de chaque envoi de message.

59
00:03:21,770 --> 00:03:22,660
Voici un autre problème.

60
00:03:23,310 --> 00:03:28,260
On a une classe book, une
méthode borrow, et quand on l'exécute

61
00:03:28,460 --> 00:03:31,450
on obtient le message que
nil ne comprend pas ifFalse.

62
00:03:32,500 --> 00:03:37,390
On envoie le message ifFalse
ici à nil, ça veut dire que

63
00:03:37,590 --> 00:03:40,180
in library à la valeur nil
qui est la valeur par défaut

64
00:03:40,380 --> 00:03:43,420
pour toutes les variables,
ce qu'on peut se dire c'est

65
00:03:43,620 --> 00:03:45,430
que probablement in
libray n'a jamais initialisé.

66
00:03:46,580 --> 00:03:50,740
Donc il faut donc mettre une valeur
par défaut dans cette variable-là.

67
00:03:51,890 --> 00:03:54,910
On peut corriger ça assez
facilement, en ajoutant une

68
00:03:55,110 --> 00:03:59,730
méthode initialize qui dès
la création de l'instance de

69
00:04:00,290 --> 00:04:03,830
chaque instance de la
 classe book, va mettre la valeur

70
00:04:04,030 --> 00:04:07,300
true dans la variable
d'instance in library.

71
00:04:07,720 --> 00:04:10,430
Sauf que si on exécute ce
code-là maintenant, on va avoir

72
00:04:10,630 --> 00:04:14,720
un autre message d'erreur
qui est class true ne comprend

73
00:04:14,920 --> 00:04:15,690
pas le message ifFalse.

74
00:04:15,890 --> 00:04:18,640
D'où est-ce que ça vient ?

75
00:04:19,420 --> 00:04:23,720
Ce qu'on a mis ici c'est
une classe, ce n'est pas un

76
00:04:23,920 --> 00:04:25,050
booléen c'est une classe.

77
00:04:26,130 --> 00:04:29,170
Le booléen c'est true
avec un T minuscule.

78
00:04:30,570 --> 00:04:34,010
Les classes prennent en
général une majuscule.

79
00:04:35,020 --> 00:04:38,000
Et donc true avec un T
majuscule c'est une classe et true

80
00:04:38,200 --> 00:04:41,040
avec un T minuscule, c'est la
seule instance de la classe true.

81
00:04:42,060 --> 00:04:43,850
Voici un autre problème.

82
00:04:44,310 --> 00:04:46,430
On a une méthode roll dans
une classe dice, on s'attend à

83
00:04:46,630 --> 00:04:49,640
ce que quand on fait rouler
un dé, on obtienne un nombre

84
00:04:50,000 --> 00:04:53,470
entre 1 et le nombre de
faces du dé, sauf que là, quand

85
00:04:53,670 --> 00:04:57,530
on fait rouler le dé,
on obtient un dé et pas

86
00:04:58,720 --> 00:05:00,010
la face sur laquelle on est tombé.

87
00:05:01,490 --> 00:05:04,270
La méthode que je viens de
vous montrer est équivalente à

88
00:05:04,470 --> 00:05:08,100
la méthode ci-dessous,
c'est-à-dire que, par défaut, une

89
00:05:08,300 --> 00:05:10,500
méthode qui ne
renvoie rien renvoie self.

90
00:05:11,660 --> 00:05:14,430
C'est-à-dire que notre méthode
roll, quand elle va s'exécuter,

91
00:05:14,630 --> 00:05:17,650
elle va retourner le dé et
non pas le résultat d'envoyer

92
00:05:17,850 --> 00:05:21,690
at random à

93
00:05:23,000 --> 00:05:23,750
la collection faces.

94
00:05:25,040 --> 00:05:27,440
Donc le même problème dans un
exemple un petit peu différent.

95
00:05:28,080 --> 00:05:32,570
Ici on crée une méthode
new dans la classe dice,

96
00:05:33,650 --> 00:05:36,250
donc dans dice class ce
qu'on veut c'est faire une

97
00:05:36,450 --> 00:05:38,920
nouvelle méthode pour créer
des instances de la classe

98
00:05:39,120 --> 00:05:42,860
dice qui initialise, par
défaut, le nombre de face à zéro.

99
00:05:44,190 --> 00:05:47,320
Si on envoie le message new
à la classe dice, ce qu'on va

100
00:05:47,520 --> 00:05:50,460
obtenir c'est la classe
dice elle-même plutôt qu'une

101
00:05:50,660 --> 00:05:51,540
nouvelle instance de la classe dice.

102
00:05:53,330 --> 00:05:56,950
Dans les 2 cas, le fait
qu'il n'y ait pas de return self

103
00:05:57,150 --> 00:05:59,470
et self, par
défaut, c'est le receveur.

104
00:05:59,670 --> 00:06:02,690
Donc dans le cas d'une méthode
de classe, self c'est la classe.

105
00:06:03,440 --> 00:06:07,110
Pour corriger ces 2
problèmes, il suffit d'ajouter le

106
00:06:07,310 --> 00:06:09,310
chapeau pour retourner une
valeur bien particulière.

107
00:06:11,250 --> 00:06:16,030
Problème suivant. Si ce
code-là est exécuté, le

108
00:06:16,230 --> 00:06:20,900
système semble être bloqué,
il ne se passe plus rien et

109
00:06:21,100 --> 00:06:22,780
impossible d'interagir avec Pharo.

110
00:06:24,170 --> 00:06:25,110
D'où vient ce problème ?

111
00:06:25,540 --> 00:06:28,500
Le problème vient du fait
qu'on est en train d'implémenter

112
00:06:28,700 --> 00:06:30,040
une méthode new dans dice classe.

113
00:06:30,330 --> 00:06:33,720
Self c'est Dice,

114
00:06:36,520 --> 00:06:39,870
et donc self new va se
rappeler récursivement.

115
00:06:41,380 --> 00:06:44,790
Ce qu'on a voulu faire ici,
c'est utiliser l'initialisation,

116
00:06:45,000 --> 00:06:47,740
la création d'instance par
défaut définie dans la super

117
00:06:47,940 --> 00:06:50,700
 classe de Dice, et ensuite
ajouter des choses par rapport à ça.

118
00:06:51,650 --> 00:06:53,600
En l'écrivant comme ça,
on a une boucle infinie.

119
00:06:54,910 --> 00:06:59,520
Il faut remplacer self par
super pour demander l'implémentation

120
00:07:00,870 --> 00:07:01,630
de la super-classe.

121
00:07:03,070 --> 00:07:04,730
Ce que vous devez retenir.

122
00:07:06,520 --> 00:07:08,650
Donc on commet tous
beaucoup d'erreurs.

123
00:07:08,850 --> 00:07:10,470
Les erreurs que je vous ai
présentées sont des erreurs

124
00:07:10,670 --> 00:07:13,500
très, très fréquemment commises
par tous les développeurs Pharo.

125
00:07:14,340 --> 00:07:17,310
Il y a des choses qu'on
retrouvent très régulièrement:

126
00:07:18,170 --> 00:07:23,000
les points qui
manquent, les parenthèses, le

127
00:07:23,200 --> 00:07:25,540
chapeau qui manque ou yourself.

128
00:07:27,060 --> 00:07:30,490
Essayez d'utiliser un maximum le
débugger pour trouver l'origine

129
00:07:30,690 --> 00:07:32,640
du problème. Vous verrez
que le débugger vous aide

130
00:07:32,840 --> 00:07:35,820
vraiment et qu'il ne vaut
mieux pas le fermer dès qu'il

131
00:07:36,020 --> 00:07:39,200
s'ouvre, parce que vous loupez
une façon de corriger les problèmes.

