JeuWeb - Crée ton jeu par navigateur
[JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! (/showthread.php?tid=7068)

Pages : 1 2 3 4 5 6 7 8 9 10 11


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - srm - 01-08-2013

C'est vrai ce que tu dis, mais dans tous les cas. Même le tien.
Parce que si par exemple l'identifiant est un "Integer" il sera forcément utilisé à un moment à l'extérieur de ta bibliothèque par des autres parties du programme, quelle que soit la façon dont tu programmes.

Donc c'est un faux problème que tu cites Smile


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - niahoo - 01-08-2013

Toute façon faut utiliser des map et pas des foreach.

Ta bibliothèque expose une méthode map qui prend une fonction de type Integer -> Integer. C'est aux programmes qui appellent cette API de rester compatibles. Ils savent qu'ils vont recevoir un Integer, et qu'ils vont devoir en renvoyer un nouveau. C'est le contrat. La bibliothèque ne doit pas laisser l'extérieur travailler directement avec ses données, elle doit leur faire lire les données puis récupérer les changements proposés et les valider ou soulever une exception.

Donc comme le dit Xenos ça sera bien la biliothèque qui gèrera le "message" de modification mais c'est bien de l'extérieur qu'on choisira comment on fait cette modification.

Enfin, ça dépend comment on code aussi, y en a qui vont "hardcoder" toutes les modifications possibles dans la classe Biblithèque jusqu'à faire un fichier de 10000 lignes Smile
Et d'un autre côté t'aura la p'tit biblio qui va juste donner des Integer et les récupérer tant qu'ils sont valides, et si à la place on lui rend un LivrePerdu elle va logger tout ça sans se plaindre.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 01-08-2013

@Oxman : Pas si la bibliothèque s'auto-initialise :p
Oui, c'est pas encore parfait, mais ce n'est pas une raison pour ne pas essayer de tendre à la perfection. De plus, une autre idée m'est venue par la suite: supposons que l'on veuille traduire les livres mot à mot (parce qu'on est nul en anglais). La méthode que tu présente prendrai un livre, traduirait le livre mot à mot, et le reposerai. Supposons qu'on ai un algorithme parallèle capable de traduire rapidement 1 seul mot dans plusieurs livres en même temps: impossible de l'implémenter si tu te base sur des "foreach (Livre in Bibliotheque)", puisque tu traiteras forcément livre à livre et non le mot à travers tous les livres.

Map me semblerait effectivement un peu plus approprié. Mais après, oui, comme le souligne niahoo, c'est très dépendant des habitudes du programmeur. "L'hardcode" a l'avantage de faire speeder la bibliothèque, et cela évite les sur-généralisations: si mon projet a besoin de manipuler des matrices 3x3 que je sais être toujours inversibles (car ce sont des rotations par exemple), alors je ne vais pas m'encombrer d'une bibliothèque qui gère tout type de matrice, NxM incluses, en ajoutant toute la lourdeur d'utilisation et de calcul possible (la seule limite à l'informatique étant la vitesse de calcul, quasiment tous les algorithmes actuels ont été "inventés" il y a une bonne trentaine d'années mais ne peuvent être vraiment utilisés que maintenant).

Pour en revenir à la base, l'idée est de ne plus considérer la bibliothèque comme une collection d'objets indépendants, mais comme un ensemble mono-bloc, que ce soit en entrée, sortie ou autre.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - srm - 01-08-2013

Aucun rapport avec le fait qu'elle s'auto-initialise.
Ne mélange pas tout, je n'ai jamais dit qu'il ne fallait pas faire comme tu dis, je dis au contraire que ça dépend beaucoup tu travailles à faire alors que toi tu dis qu'il faut tendre à toujours le faire.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 01-08-2013

Par l'auto-initialisation, j'entendais que si la bibliothèque n'est pas remplie élément par élément ni traitée élément par élément (donc, vu comme un tout indivisible et non comme une tableau), alors l'élément contenu ne sera jamais utilisé à l'extérieur (puisque de l'extérieur, la bibliothèque est indivisible).

Tendre à toujours le faire, oui. Mais je n'ai pas dit qu'il faut mettre au placard les collections / tableaux d'objets. Disons que je pense qu'il faudrait distinguer la classe qui est vue normalement comme un tout indivisible (boîte noire) et les collections / tableaux d'objets qui ne devraient pas être vus comme des classes (puisqu'on traite leur contenu "un à un"). Il me semble que la bonne pratique consiste à avoir des classes de type "boite noire" (principe de l'OO me semble-t-il, non?). Et si une classe est une simple collection d'objets que l'on peut manipuler l'un après l'autre (à l'écriture, la lecture ou la modification ou autre), alors la collection n'est pas vue comme une boite noire, puisqu'on en demande et traite ses composants internes. C'est cela que je trouve être une mauvaise pratique (mais de toute façon, je n'ai ni le droit, ni la notoriété ni l'opportunité de forcer les gens à faire ainsi, libre à chacun de procéder comme il le souhaite, le but étant d'avoir un code que l'on sache relire et maintenir, pas de faire "ce que les autres ont en tête juste pour faire bien / faire plaisir").

Donc, oui, cela dépend du travail à faire car dans certains cas, on a besoin d'un Array (qui ne devrait, à mon sens, être rien de plus qu'un Array, et non un véritable objet), alors que dans d'autres cas, si on veut traiter ce "array" comme un vrai objet, on ne devrait pas s'attacher aux différents éléments qui le composent, car on n'est pas censé connaitre ce qui compose l'objet lui-même.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - niahoo - 01-08-2013

traduire un seul mot dans plusieurs livres à la fois ...

Donc, prenons le mot that, donc je fais quoi, j'ai une fonction qui traduit ce mot, et ... je prends quand même mes livres un par un au final, puis je traduis toutes les occurences de ce mot dans chaque bouquin.

ça ne change rien, tu peux paralelliser la traduction de plusieurs livres mot-à-mot en même temps, ou paralleliser la traduction de chaque mot en même temps. Sauf que tu ne sais pas si tel mot est présent dans tel bouquin. Tu vas donc prendre chaque bouquin, le parcourir en entier pour voir si le mot est présent, traduire les occurences du mot si on en trouve et reposer dans la bibliothèque un livre mi-anglais mi-français ... si à un moment ton thread qui se souvient à quel mot on en est plante, tu peux recommencer au début.

Ah et je ne parle pas du fait que that peut être traduit de plusieurs manières selon le sens et qu'il te faudra donc de toute façon traduire des phrases entières pour seulement remplacer le mot ... et le mot suivant devra déduire le sens d'une phrase à moitié en anglais pour simplement traduire un seul mot ... bancal.

Non, la bibliothèque devrait servir à stocker des livres et c'est tout. Si tu traduis les livres 1 par 1 (en parallèle si tu veux), ben si ça plante, tu recommences la traduction de ton livre, mais pas les autres, qui sont soit en français, soit en anglais. Je récupère la liste des bouquins, et pour chaque élément je demande le livre à la bibliothèque (une copie du livre en fait), puis je lui donne à stocker un autre bouquin, en lui disant éventuellement que ce nouveau bouquin est une traduction de l'autre.

Je peux donc facilement interfacer une lib de traduction de textes avec ma lib de gestion de bouquins, et chacun reste indépendant.

Donc d'une part ta solution ne fait pas gagner de temps, bien au contraire, elle utilise des données mutables dont l'état peut être indéfini et en plus elle n'est pas "tolérante aux crash".


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 01-08-2013

La traduction mot à mot, osef de la qualité (tu n'as qu'à imaginer qu'au lieu de traduire, je code mes livres, avec un code très simple à base de substitution directe d'un mot avec un autre). Là où j'aimerai me faire comprendre (mais apparemment, j'ai du mal, en fait, cela me dépayse pas trop, j'ai souvent eu des retours type "ah putain, ton idée était tordue, personne n'aurait pensé ça comme ça, mais finalement, ça marche plutôt bien") c'est que le principe que vous avez en tête, c'est:
j'ai une classe, bibliothèque, et je veux pouvoir lui demander un livre (l'un après l'autre, ou tous d'un coup, ou autre, osef) pour lui appliquer un traitement.

Mais cela me semble aller partiellement à l'encontre du principe objet, qui consiste (alors, peut être que je me trompe sur ce principe, auquel cas, corrigez moi) à ne rien connaître du contenu de l'objet que l'on manipule.

C'est comme Schrodinger et son chat: on se fiche de savoir si le chat est mort ou vivant, ce qui est intéressant, c'est de voir que la question en elle-même n'a pas de sens. Dans le cas de la bibliothèque, si on la voit comme un objet, ça n'a juste pas de sens de vouloir récupérer ce qui compose cette bibliothèque, puisque cela est censé faire partie de la "boite noire" de la bibliothèque.
Il me semble que ce n'est pas par hasard que le C/C++ considère les tableaux comme des types de base, et non des objets. L'idée est la même. Si on veut gérer la bibliothèque comme une collection de livres, on n'en fait pas un véritable objet (on peut toujours la coller dans une classe, mais ce ne sera pas une classe qui respecte le principe de "boite noire" de l'objet). Si on veut que la bibliothèque soit vue comme un objet, on "l'assume", et on n'autorise pas l'utilisateur à aller voir son contenu.

C'est un peu comme les getter et setters par défaut: à quoi cela rimerait-il d'avoir une classe ayant un attribut "private" (ou protected) que l'on relie à un getter et un setter par défaut? Autant faire de l'attribut un attribut "public"...

Enfin, voilà, c'est ma vision des choses (généralement, on me dit "extrémiste"...), je n'obligerai personne à suivre Wink Mais c'est une habitude de codage qui me permet de faire des traitements de plusieurs millions de données (dernier exemple en date: une maquette 3D de 10.000.000 de triangles) en moins d'une dizaine de minutes (contre 15 minutes pour seulement 10.000 triangles avec la technique du précédent groupe de travail qui justement travaillait plutôt sur du "on fout tout dans des objets même les tableaux, les matrices, les vecteurs et les types de base").

Oui, c'est un peu "hard codé", sauf que c'est la classe qui se hard code, donc, cela reste parfaitement maintenable; bien plus qu'un code hyper-généralisé partagé entre plusieurs classes / "zones" de code.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - niahoo - 01-08-2013

Je préfère traduire un bouquin correctement même si c'est un peu plus lent, mais bref, continuons.

Non, le principe objet n'est pas de ne rien savoir de ce que fait ton objet. Car à ce compte là, si je ne suis pas foutu de savoir ce qu'il y a dans ma bibliothèque, bah le lui met un joli parpaing autour du cou et je la balance du haut d'un pont.

Non, l'idée ici c'est de ne pas savoir comment fait l'objet pour faire ce qu'il fait. Mais on veut quand même récupérer des bouquins et en déposer.

Avec ta technique, il faudra ajouter des méthodes à la bibliothèque à chaque fois qu'une nouvelle appli voudra s'interfacer avec.

Bon et puis promouvoir le tout objet 'pur' pour ensuite se targuer d'utiliser des types simples je comprends pas la logique. Encore une fois tu mélanges les choses.

Perso mon langage de prédilection (Erlang) ne connaît que les types simples. (Il n'a pas d'objets syntaxiquement). Si je voulais coder une bibliothèque j'utiliserais bien sûr une simple liste, (mais j'aurais également à côté des métadonnées) mais j'autoriserais l'utilisateur à récupérer un bouquin. Ce n'est pas parce que tu laisses quelqu'un itérer sur tous tes livres que tu lui permets pour autant de niquer toutes tes données ou de supprimer des bouquins au hasard.

Regarde une base de données SQL, tu ne sais pas comment sont stockées tes données ni comment sont parsées tes requêtes. Mais la base on s'en fout, ce qui compte ce sont les données. Tu as donc une API complète pour lire les données (SELECT), les modifier (UPDATE), etc.

Mais si tu ne le fais pas correctement, tu plantes. Et si tu n'envoies pas les bonnes infos de connexion, tes droits peuvent être réduits.

Un ORM calé sur cette base te permet à son tour de ne pas gérer les appels à la base et de te concentrer sur les données. Il permet aussi de contrôler la validité des données avant enregistrement, et il te permet d'itérer sur toute une table pour changer les données à ta guise. Il te simplifie simplement le boulot en masquant la façon dont il traite avec la base.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 01-08-2013

Alors, quand tu fais un "foreach (livre in bibliothèque)", alors tu sais comment l'objet stocke ses données. Si tu as une méthode "bibliotheque.traduireTout()", alors tu ne sais pas comment se débrouille la bibliothèque pour tout traduire.
Qui te dis que le bouquin que tu récupère est celui du rayonnage? C'est là qu'est l'idée selon moi. Itérer sur tous les bouquins de la bibliothèque via forEach présume que le bouquin renvoyé est celui contenu dans la bibliothèque, et cela me semble anormal puisqu'alors tu sais comment la bibliothèque stocke ses bouquins. Si ta bibliothèque classique avec des livres papiers qui prennent la poussière et toute la place devient une bibliothèque électronique, alors ok le getLivre() peut rester, mais le livre renvoyé n'est pas le livre stocké dans la bibliothèque, puisqu'il te renvoie un livre papier alors que la bibliothèque stocke (et ça, tu ne le sais pas) des livres électroniques.
Récupérer un bouquin peut donc faire sens, mais itérer sur tous les bouquins me semble insensé.

Attention: je me suis peut-être mal exprimé, mais pour moi, le "tout objet pur" est différent du "tout est objet point barre". Un "tout objet pur" est, pour moi, un programme dans lequel tout ce qui a besoin d'être objet est objet, et tout ce qui n'a pas besoin d'être objet n'est pas objet. C'est différent d'un "tout est objet".

(J'objecterai, pour finir, que permettre d'itérer sur chaque livre c'est risquer que l'utilisateur bousille les livres, car si on ne renvoie pas un nouvel objet Livre, mais une référence, ou autre assimilé, au livre dans la bibliothèque, alors l'utilisateur peut brûler ce livre sans soucis; si c'est une base de données, cela peut faire mal).

On n'est peut-être pas de la même génération (vive les jeunots de 22 ans!), mais je préfère un objet dont je ne sais rien mais à qui je peux demander "bibliotheque.toutTraduire()" plutôt qu'un objet pour lequel je dois itérer sur son contenu (donc, je dois connaitre toute la documentation de cet objet plus celle de son contenu).
En revanche, oui, si je veux m'y interfacer, il va falloir ajouter des méthodes. Mais rien n'interdit d'avoir un héritage, et de faire une BibliothequeFille qui ajoute des méthodes à Bibliothèque, qui elle peut proposer une itération en "protected" (là, c'est possible, puisqu'on reste dans la classe: l'itérateur ne "fuite" pas hors du code de la classe).
Sinon, sans un tel itérateur, c'est vrai que c'est lourd d'ajouter des méthodes... Mais quelle facilité par la suite pour faire la maintenance, puisqu'on n'a plus aucune réelle dépendance ni "fuite" Smile


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - niahoo - 01-08-2013

C'est compliqué pour rien.

Ta bibliothèque expose une fonction map. Tu passes un callback qui reçoit un objet de type Livre et qui renvoie un objet de type Livre. Si ta fonction renvoie une référence, la bibliothèque la refuse. Si ta fonction renvoie autre chose qu'un Livre, la bibliothèque la refuse.

Au sein de ta fonction, tu peux faire ce que tu veux à ton bouquin, c'est une copie. La bibliothèque s'en fout. Ce qu'elle veut c'est que tu lui renvoie un livre qui remplacera le précédent.

Parce que au sein de ton objet, ta bibliothèque va faire des contrôles sur ce que ta fonction lui renvoie, c'est ça qui est masqué de l'extérieur.

Évidemment, ça oblige à faire des copies. Mais travailler avec des données non mutables est beaucoup plus simple. Tu as raison en disant que ça sera peut-être moins rapide, mais ça sera aussi beaucoup plus simple. Et en comparaison du temps qu'il faut pour traduire un livre, les temps de copie sont négligeables.

Sinon avec des méthodes comme toutTraduire(), il te faudra comme je le disais agrandir ta classe de façon incontrôlée.

Pour l'héritage ça peut être sympa. Sauf que ta bibliothèque elle sera peut être déjà instanciée quand tu voudras traduire. Donc le plus logique serait d'avoir une classe qui fait l'interface entre les fonctionnalités de traduction et la bibliothèque. Si elle veut pouvoir travailler sur les livres de la bibliothèque il faudra bien qu'elle itère dessus si on utilise un décorateur. On on peut utiliser une classe friend sauf qu'il faudra contrôler la "correctitude" des données dans chaque friend qui voudra pouvoir toucher aux données en plus de les déclarer friend dans la classe bibliothèque ...

Non vraiment je ne suis pas convaincu. Encore en ruby tu peux facilement patcher une classe ce qui nous rendrait heureux tous les deux Smile

Citation :On n'est peut-être pas de la même génération (vive les jeunots de 22 ans!), mais je préfère un objet dont je ne sais rien mais à qui je peux demander "bibliotheque.toutTraduire()" plutôt qu'un objet pour lequel je dois itérer sur son contenu (donc, je dois connaitre toute la documentation de cet objet plus celle de son contenu).

On parle ici d'une collection. Un objet bien fait devrait gérer ses billes, rien de plus. Dans mon modèle on ne te demande pas de comprendre comment serait faite l'itération, ni le reste de la documentation de l'objet. Simplement, au lieu de te dire que tu as cette interface :

Code :
toutTraduire (String language)

Tu as celle-ci :

Code :
replaceBooks ( (Book -> Book) callback)

Ensuite ça ne change rien.

Heu sinon j'ai 27 balais je ne comprends pas trop pourquoi tu dis ça. De toute façon l'avenir c'est le Functional Programming :p

N'empêche on pourrit bien le topic.