Bonjour,
J'ai cherché un peu mais je n'ai rien trouvé de satisfaisant sur le net. Comment écrivez-vous en switch en smalltalk ? J'ai vu une chouette implémentation mais au niveau object directement. Ca m'embête de modifier mon image et de produire un code qui ne sera plus 'portable'... Du coup de fait ainsi: vitesseVers: dir dir==#Haut ifTrue [vitesse := 0@1]. dir==#Bas ifTrue [vitesse := 0@-1]. dir==#Gauche ifTrue [vitesse := -1@]. dir==#Droite ifTrue [vitesse := 0@-1]. Et vous, vous feriez comment ? a+ Vincent _____________________________________________________________________________ Envoyez avec Yahoo! Mail. Une boite mail plus intelligente http://mail.yahoo.fr _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
dict := Dictionary new.
dict at: #Haut put: 0@1 ... vitesse := (dict at: #Haut) Stef On Aug 22, 2008, at 4:52 PM, Vincent Osele wrote: > Bonjour, > > J'ai cherché un peu mais je n'ai rien trouvé de satisfaisant sur le > net. > > Comment écrivez-vous en switch en smalltalk ? > > J'ai vu une chouette implémentation mais au niveau object directement. > Ca m'embête de modifier mon image et de produire un code qui ne sera > plus 'portable'... > > Du coup de fait ainsi: > > vitesseVers: dir > dir==#Haut ifTrue [vitesse := 0@1]. > dir==#Bas ifTrue [vitesse := 0@-1]. > dir==#Gauche ifTrue [vitesse := -1@]. > dir==#Droite ifTrue [vitesse := 0@-1]. > > > Et vous, vous feriez comment ? > > a+ > Vincent > > > > _____________________________________________________________________________ > Envoyez avec Yahoo! Mail. Une boite mail plus intelligente http://mail.yahoo.fr > _______________________________________________ > Squeak-fr mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr > _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
stephane ducasse a écrit :
>> Comment écrivez-vous en switch en smalltalk ? > dict := Dictionary new. > dict at: #Haut put: 0@1 > ... > > vitesse := (dict at: #Haut) Marrant comme implémentation, je garde ! En plus, cela peut être déclaré en tant qu'instance de classe donc pas gourmand. a+ Vincent _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
In reply to this post by vicnet
Bonjour,
La philosophie générale de Smalltalk consiste à décomposer ses traitements en petites méthodes. Mettre un switch au milieu de son code est donc généralement considéré comme une mauvaise pratique. Il est plutôt conseillé de sortir son switch en une méthode à part et de sortir de la méthode dès que possible. Dans ton cas, cela donne : vitesseVers: dir dir==#Haut ifTrue [^0@1]. dir==#Bas ifTrue [^0@-1]. dir==#Gauche ifTrue [^-1@0]. dir==#Droite ifTrue [^-1@0]. self error: 'direction inconnue : ', dir printString Cordialement, Jean-François Vincent Osele a écrit : > Bonjour, > > J'ai cherché un peu mais je n'ai rien trouvé de satisfaisant sur le net. > > Comment écrivez-vous en switch en smalltalk ? > > J'ai vu une chouette implémentation mais au niveau object directement. > Ca m'embête de modifier mon image et de produire un code qui ne sera plus 'portable'... > > Du coup de fait ainsi: > > vitesseVers: dir > dir==#Haut ifTrue [vitesse := 0@1]. > dir==#Bas ifTrue [vitesse := 0@-1]. > dir==#Gauche ifTrue [vitesse := -1@]. > dir==#Droite ifTrue [vitesse := 0@-1]. > > > Et vous, vous feriez comment ? > > a+ > Vincent > > > _____________________________________________________________________________ > Envoyez avec Yahoo! Mail. Une boite mail plus intelligente http://mail.yahoo.fr > _______________________________________________ > Squeak-fr mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr > > > > -- *Jean-François LEFEVRE* Architecte Senior +33 (0)6 80 38 01 29 [hidden email] <mailto:[hidden email]> 268, avenue du Président Wilson 93210 LA PLAINE-SAINT-DENIS Std : +33 1 55 93 26 00 - Fax : +33 1 55 93 26 01 *"SQLI Consulting, l'expert du conseil IT"* www.sqli.com <http://www.sqli.com> /---------------------------------------------------------------------------------- Ce message et toutes les pièces jointes (ci-après le "message") sont confidentiels et établis à l'intention exclusive de ses destinataires. Toute utilisation ou diffusion non autorisée est interdite. Tout message électronique est susceptible d'altération. ---------------------------------------------------------------------------------- / _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
In reply to this post by vicnet
> vitesseVers: dir > dir==#Haut ifTrue [vitesse := 0@1]. > dir==#Bas ifTrue [vitesse := 0@-1]. > dir==#Gauche ifTrue [vitesse := -1@]. > dir==#Droite ifTrue [vitesse := 0@-1]. > > > Et vous, vous feriez comment ? > > a+ > Vincent vitesse := dir caseOf: { [#Haut] -> [0@1]. [#Bas] -> [0@-1]. [#Gauche] -> [-1@0]. [#Droite] -> [1@0]. } Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
Merci de ne pas utiliser caseOf: c'est vraiment horrible. est un hack
qui reste dasn squeak mais n'existe pas dans les autres dialectes. stef On Aug 25, 2008, at 5:41 PM, Stéphane Rollandin wrote: > >> vitesseVers: dir >> dir==#Haut ifTrue [vitesse := 0@1]. >> dir==#Bas ifTrue [vitesse := 0@-1]. >> dir==#Gauche ifTrue [vitesse := -1@]. >> dir==#Droite ifTrue [vitesse := 0@-1]. >> Et vous, vous feriez comment ? >> a+ >> Vincent > > vitesse := dir caseOf: { > [#Haut] -> [0@1]. > [#Bas] -> [0@-1]. > [#Gauche] -> [-1@0]. > [#Droite] -> [1@0]. > } > > > > Stef > > _______________________________________________ > Squeak-fr mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr > _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
stephane ducasse a écrit :
> Merci de ne pas utiliser caseOf: c'est vraiment horrible. est un hack > qui reste dasn squeak mais n'existe > pas dans les autres dialectes. > stef sans doute, mais c'est la seule réponse techniquement correcte à la question posée: quel est l'équivalent du switch. ... ensuite il faut un peu de temps pour comprendre comment on pense object au lieu de penser en switch et là il n'y a plus de réponse simple, même si ça devient très intéressant AMA. Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
2008/8/26 Stéphane Rollandin <[hidden email]>:
> sans doute, mais c'est la seule réponse techniquement correcte à la question > posée: quel est l'équivalent du switch. le switch c'est le message lookup :) Object subclass: #Direction Direction subclass: #Haut Haut >> vector ^ 0@1 ou alors implémenter #haut #bas... dans la même classe et faire un perform: -- Damien Pollet type less, do more [ | ] http://people.untyped.org/damien.pollet _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
Damien Pollet a écrit :
> 2008/8/26 Stéphane Rollandin <[hidden email]>: >> sans doute, mais c'est la seule réponse techniquement correcte à la question >> posée: quel est l'équivalent du switch. > > le switch c'est le message lookup :) non, pas du point de vue pratique. utiliser un dictionaire, ok (mais en fin de compte quelle est la différence conceptuelle entre implémenter un lookup via une classe, dictionaire, et une méthode, caseOf: ? pourquoi l'un sortirait des clous "c'est de l'objet" et pas l'autre ?) en revanche, implémenter un message pour #haut, #bas, etc... ça ce serait vraiment du mauvais design objet AMHA. Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
un dictionaire cela veut dire que l'on peut etendre le comportement
sans copier copier et modifier tous les cases. stef On Sep 28, 2008, at 1:33 PM, Stéphane Rollandin wrote: > Damien Pollet a écrit : >> 2008/8/26 Stéphane Rollandin <[hidden email]>: >>> sans doute, mais c'est la seule réponse techniquement correcte à >>> la question >>> posée: quel est l'équivalent du switch. >> le switch c'est le message lookup :) > > non, pas du point de vue pratique. utiliser un dictionaire, ok (mais > en fin de compte quelle est la différence conceptuelle entre > implémenter un lookup via une classe, dictionaire, et une méthode, > caseOf: ? pourquoi l'un sortirait des clous "c'est de l'objet" et > pas l'autre ?) > > en revanche, implémenter un message pour #haut, #bas, etc... ça ce > serait vraiment du mauvais design objet AMHA. > > Stef > > _______________________________________________ > Squeak-fr mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr > _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
stephane ducasse a écrit :
> un dictionaire cela veut dire que l'on peut etendre le comportement sans > copier copier et modifier tous les cases. > oui, c'est une différence importante, mais d'ordre pratique, pas conceptuel. mais voici un exemple de caseOf: supposons que je veuille implémenter un langage abscons pour parler à des nombres: 4 ga -> 8 4 zo -> 9 4 bu -> -4 4 meuh -> -8 Number>>shadock: symbol ^ symbol caseOf: { [#ga] -> [2* self]. [#zo] -> [2* self + 1]. [#bu] -> [self negated]. [#meuh] -> [2* self negated] } otherwise: ['gazo ?'] dans cet example, l'extensivité du dictionnaire n'apporterait rien, car les shadocks n'ont que quatre mots et sont contents avec. par rapport à l'implémentation directe #ga, #zo, #bu et #meuh comme méthode de la class Integer, on gagne le fait que le langage shadock est clairement délimité. en effet on devrait faire Number>>shadock: symbol (#(ga zo bu meuh) identityIncludes: symbol) ifFalse: [^ 'gazo ?']. ^ self perform: symbol si l'on veut obtenir le 'gazo ?' outragé que l'on attend lorsqu'on parle mal le shadock. reste le dictionaire. ce serait Number>>shadock: symbol | dict | dict := IdentityDictionary new. dict add: #ga -> [:n | 2* n]. dict add: #zo -> [:n | 2* n+ 1]. dict add: #bu -> [:n | n negated]. dict add: #meuh -> [:n | 2 * n negated]. ^ (dict at: symbol ifAbsent: [^ 'gazo ?']) value: self cela ne me parait pas plus beau que le caseOf:, et c'est peut-être plus lent (j'ai pas vérifié) car il faut recréer le dictionaire à chaque invocation. évidemment on pourrait créer le dictionaire une fois pour toute, mais cela suppose une nouvelle variable d'instance ou de classe quelque part. si je veux distribuer mon langage idiot, c'est quand même mieux s'il consiste en une simple méthode qui ne requiert pas que l'on recompile la classe Integer pour lui ajouter une variable ShadockDictionary, non ? Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
"extensibilité du dictionnaire", pas "extensivité du dictionnaire",
pardon :) Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
In reply to this post by Stéphane Rollandin-2
2008/9/28 Stéphane Rollandin <[hidden email]>:
> évidemment on pourrait créer le dictionaire une fois pour toute, mais cela > suppose une nouvelle variable d'instance ou de classe quelque part. si je > veux distribuer mon langage idiot, c'est quand même mieux s'il consiste en > une simple méthode qui ne requiert pas que l'on recompile la classe Integer > pour lui ajouter une variable ShadockDictionary, non ? Mais à la base, étendre Number c'est pas très joli :) Au lieu de Number >> shadock: aSymbol il vaudrait mieux : Shadock >> pumpWithNumber: aNumber redéfinie dans quatre sous-classes de Shadock et Shadock class >> fromSymbol: aSymbol et ça fait sens de mettre un dictionnaire dans Shadock pour savoir quelle sous-classe instancier. -- Damien Pollet type less, do more [ | ] http://people.untyped.org/damien.pollet _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
In reply to this post by stephane ducasse
Bonjour,
Un dictionnaire mais seulement si il est déclaré une fois pour toute. Surtout pas un dictionnaire créé et renseigné dans la méthode juste avant son utilisation (trop lourd). En regardant d'un peu plus près l'exemple de la direction on se rend compte qu'on veut passer d'une représentation d'un concept sur un autre concept ou sur une autre représentation. Ici, on veut passer d'une représentation du concept de direction sous forme de symbole vers une représentation sous forme de Point (ou plutôt de Vecteur). Le réflexe qu'on doit avoir selon moi c'est de ce demander si on n'est pas passé à coté d'un objet. Effectivement, ici on manipule un concept de Direction qui n'est pas clairement défini en tant qu'objet. Il est donc probable que mon code serait plus "Orienté Objet" avec une classe Direction. Dans notre cas présent, il semble qu'on gère 4 directions particulières (haut, bas, droite et gauche). Il semble donc intéressant de spécifier 4 instances particulières, constantes, qu'on placera certainement dans des variables de classe ou dans des variables d'instances de classes. Peu importe la manière de conserver ces instances, il estprobable que j'aurai envie de proposer un accès à ces instances et donc je placerai des méthodes de classe comme haut, bas, droite et gauche dans ma classe Direction. Que sait faire un objet Direction ? Certainement un tas de choses comme me donner un vecteur sous forme d'un Point (la méthode vector dont parle Damien dans un message précédent). On peut se contenter dans un premier temps de conserver cette information dans un attribut d'instance propre à chaque instance de Direction. Si le comportement des objets Direction devait vraiment être très différent selon l'instance, on pourrait effectivement envisager de faire des sous classes pour chaque direction mais on n'a peut être pas besoin d'aller jusque là pour cet exemple (faire des hiérarchies de classes complique souvent les choses). Est-ce que cela élimine tous besoin d'un switch ? la réponse est malheureusement non. Il y a forcément un moment où je vais devoir récupérer une instance et où je vais me demander laquelle. Par exemple si je dois récupérer l'instance correspondant à un caractère frappé au clavier ou si je veux implémenté une méthode comme #normal donnant la direction à 90 degrés. Une possibilité est d'ajouter une information dans la classe Direction et d'offrir accès à la liste des instances (ici des quatres constantes). Ainsi, je peux faire une recherche dans cette collection. Par exemple, on peut ajouter l'information #name et donc faire une boucle de recherche par nom sur cette collection. Si ce besoin est fréquent, on va certainement offrir une méthode d'accès effectuant cette recherche, ce qui pourrait donner : directionNamed: aSymbol "answer the constant named aSymbol or raise an exception" ^self directions detect: [:each | each name = aSymbol] Evidemment, il est tentant de faire un #perform: (à déconseiller vivement car on ne contrôle plus ce qui se passe avec un symbole quelconque) directionNamed: aSymbol "answer the constant named aSymbol or raise an exception" ^self perform: aSymbol Ca n'est pas toujours souhaitable d'enrichir la classe de cette manière. Il y a toujours des cas où on retombe sur la question "Passer d'un concept à un autre". Ici l'exemple de la méthode #normal commencerait à devenir limite (on va pas ajouter à chaque instance un attribut pour donner sa #normal et aussi sa transposé ou son inverse). Si on reste dans le cadre des quatres constantes on va donc se faire une séquence de if du genre : normal "answer the direction rotated 90 deg" self == self class haut ifTrue: [^self gauche]. self == self class gauche ifTrue: [^self bas]. self == self class bas ifTrue: [^self droite]. self == self class droite ifTrue: [^self haut]. self error: 'You have created other Direction instance !!!' Remarque : on pourrait évidemment supporter des instances constantes et non constantes. Dans ce cas précis on pourrait utiliser un dictionnaire (stocké quelque part dans la classe) et remplaçant la séquence de tests par un accès plus performant (à mesurer) ça pourrait donc donner : normal "answer the direction rotated 90 deg" ^self class normalsDictionary at: self ifAbsent: [self error: 'You have created other Direction instance !!!'] Que dire de plus ? Expliquer l'intérêt de toute cette prise de tête alors qu'un bon switch semblerait plus simple. Stéphane donne la réponse. Que se passe-t-il si on veut faire évoluer, par exemple en offrant maintenant les 4 directions supplémentaires hautDroite, hautGauche, basDroite et basGauche. L'objectif de tout ça est de diminuer les impacts sur le code utilisant la classe et si possible de faire en sorte que les impacts ne soient que des ajouts (de classes ou de méthodes) et non des modifications de méthodes existantes. Faire des switch dans son code client implique de prendre en compte les nouveaux cas. L'exemple de départ était la méthode vitesseVers: dir dir==#Haut ifTrue [vitesse := 0@1]. dir==#Bas ifTrue [vitesse := 0@-1]. dir==#Gauche ifTrue [vitesse := -1@]. dir==#Droite ifTrue [vitesse := 0@-1]. On voit bien que la prise en compte de quatre nouvelles directions impose de modifier cette méthode et certainement tout un tas d'autre. Proposer des alternatives (dictionnaires par exemple) avec des vrais objets permet de déporter ces switch dans un unique endroit (la classe Direction). Ca devient la responsabilité du développeur de cette classe de maintenir la cohérence des dictionnaires (ici le normalsDictionary par exemple) et non celle du client de se maintenir à jour. Bon, je voulais mettre mon grain de sel et voilà que j'ai versé tout le paquet. Désolé pour la longueur Jean-François Le 28 septembre 2008 13:47, stephane ducasse <[hidden email]> a écrit : un dictionaire cela veut dire que l'on peut etendre le comportement sans copier copier et modifier tous les cases. _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
In reply to this post by Damien Pollet
> Mais à la base, étendre Number c'est pas très joli :)
> Au lieu de Number >> shadock: aSymbol > il vaudrait mieux : Shadock >> pumpWithNumber: aNumber > redéfinie dans quatre sous-classes de Shadock > et Shadock class >> fromSymbol: aSymbol > et ça fait sens de mettre un dictionnaire dans Shadock pour savoir > quelle sous-classe instancier. un peu lourd quand même, une nouvelle classe et quatre sous-classes pour simplement implémenter un petit pompage numérique... d'autre part, on part d'un nombre et on obtient un autre nombre, le shadock n'étant ici qu'un vague concept réunissant #ga, #zo, #bu et #meuh donc il ne me semble pas si inadéquat d'étendre Number dans ce cas. question de style personnel je suppose.. Stef _______________________________________________ Squeak-fr mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr |
Free forum by Nabble | Edit this page |