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.