7
votes

Utilise des mélanges de chaîne pour le code réutiliser un anti-motif?

Pour ceux d'entre vous qui ne connaissent pas les mixines de chaîne, ils sont fondamentalement compilés. Vous pouvez prendre n'importe quelle chaîne d'heure de compilation (à savoir une évaluation de la fonction de métaprogrammation de modèle ou de la fonction de compilation) et de la compiler en tant que code. Si vous utilisez un simple littéral à chaîne, c'est essentiellement la pâte de copie automatisée de compilateur.

Souhaitez-vous considérer un anticipé d'utiliser des mélanges de chaînes de littéraux comme un moyen de réutilisation de code simple où d'autres méthodes d'affacturage ne correspondent pas parfaitement? D'une part, il s'agit essentiellement d'une copie littérale automatisée et d'une pâte littérale, ce qui signifie qu'une fois mélangé dans les cas n'a rien à faire avec l'autre. Les mauvaises choses se produiront (bien que lors de la compilation, pas au moment de l'exécution) Si un symbole du mixin de chaîne collecte avec un symbole dans la portée mixte. Il est relativement non structuré en ce que l'on peut, par exemple, mélanger une chaîne au milieu d'une fonction qui fonctionnera si et uniquement si les variables dans la portée sont nommées selon une certaine convention. Les mélanges peuvent également déclarer des variables que les champs extérieurs peuvent ensuite utiliser à leur guise.

D'autre part, car la copie-and-coller est compilateur automatisée, il existe un point de vérité unique pour le code en question au niveau source et s'il doit être modifié, il suffit de modifier dans Un endroit, et tout reste en synchronisation. Les mélanges de chaîne simplifient également de manière visible la réutilisation du code qui est très difficile à facteur de toute autre manière et aurait autrement une probabilité très élevée d'être coupée manuellement et collé manuellement.


0 commentaires

3 Réponses :


11
votes

Toutes les critiques que vous avez soulevées sont vraies.

Quoi qu'il en soit, il est toujours supérieur à la copie manuelle.

En réalité, j'ai quelque chose de similaire à ma bibliothèque d'outils, expansion de la table de cordes. Exemple de code, à partir d'une mise en oeuvre dynamique de la valeur dynamique de chemin de traqueur: xxx

Je suis sûr qu'il est facile de voir quel désordre horrible et redondant d'instructions imbriquées et des déclarations de cas qui serait sans Mélangements à chaîne - De cette façon, toute la laideur est concentrée en bas et le comportement réel de la fonction est facile à lire en un coup d'œil.


2 commentaires

sniff Je te sens, ressens. Celui-ci est vraiment une de vos idées plus impressionnantes.


Chaque astuce semi-soignée de manière crédible ait trois ou quatre idées qui sont simplement simples horribles - comme l'analyseur graphique de la machine à base de texte CTFE enterré profondément dans Outils.Base :)



3
votes

tandis que d'autres solutions plus élégantes peuvent être mieux à utiliser si vous le pouvez, les mélanges de chaîne peuvent être extrêmement utiles. Ils permettent la réutilisation de code et la génération de codes. Ils sont vérifiés à l'heure de la compilation. Le code qui résulte est exactement le même que si vous l'avez écrit vous-même par la main, donc ce n'est pas moins sûr que si vous l'aviez écrit vous-même à la main.

Le problème avec les mixines de chaîne est qu'ils sont plus difficiles à Contrôle que le code écrit à la main En ce sens qu'il n'est pas traité physiquement dans votre source de la même manière avec des numéros de ligne clairement traçables aux erreurs, et il peut être plus difficile de déboguer. Par exemple, prenez Hello World avec un mixage de chaîne: xxx

si nous devions supprimer le point-virgule après Writeln () , alors l'erreur que nous avons eue serait xxx

Le mixin est effectué en ligne 5. La ligne 7 est une ligne vide. Donc, le numéro de ligne est d'une utilité limitée ici. Maintenant, ce mixin est suffisamment court que nous aurions pu le mettre sur une seule ligne et l'avoir obtenu de dire que l'erreur était sur la même ligne que le mixin, mais avec des mélanges plus compliquées, qui ne fonctionneront évidemment pas. Ainsi, en utilisant un mixage de chaîne, votre capacité à déterminer où une erreur est altérée. Si le code est généré à l'aide de CTFE, il deviendrait alors beaucoup plus difficile de comprendre exactement ce que le code ressemble même à ce que le code ressemble peut-être afin de déterminer ce qui ne va pas avec elle. Cela ressemble beaucoup à ce que le code une macro de style C se transforme, sauf que cela pourrait être pire car ils pourraient être générés plutôt qu'un remplacement direct. Cependant, ils ne remplacent pas sauf où vous leur dis explicitement de leur dire, de sorte qu'ils sont beaucoup plus sûrs que les macros de style C.

Les mélanges à cordes sont totalement sûres et il n'y a rien de particulièrement erroné avec eux, mais ils n'ont rien de particulièrement erroné, mais ils ne sont rien de particulièrement erronés faire de la maintenance plus difficile à certains égards. Le code manuel correspondant serait plus facile à déboguer. Cependant, les mélanges de chaîne sont suffisamment puissants pour pouvoir faire beaucoup de génération de code pour vous et vous faire économiser de nombreux coûts de garde en ce sens, et ils vous permettent de réutiliser le code, qui peut également être un gain de grande époque.

Donc, si vous utilisez un mélange de chaîne, c'est une bonne idée dans une situation particulière dépend de cette situation. Je ne vois rien de particulièrement faux avec eux et je ne les appellerai certainement pas un anti-motif, mais il y a à la fois des avantages et des inconvénients pour les utiliser de manière à ce que ce soit une bonne idée dépend de ce que vous faites. . Dans de nombreux cas, il y a des solutions plus élégantes et plus propres qui seraient meilleures. Dans d'autres, ils sont exactement ce que le médecin a commandé.

Personnellement, je pense qu'ils sont fantastiques si vous cherchez à générer du code, vous économiserez l'effort de devoir écrire ce code à la main, Et éventuellement, il est plus facile de générer du code correct pour une variété de situations et d'éviter de risquer de créer de nouveaux bugs comme vous l'avez peut-être disposé vous-même écrit dans chacun de ces endroits où vous avez utilisé le mixin. Il est également l'un des moyens de simplement utiliser le code de réutilisation de manière simple sans avoir à s'inquiéter du coût d'un appel de la fonction ou des problèmes liés aux limites d'un seul héritage ou de quoi que ce soit d'autre, qui rend la réutilisation de code par appel de fonctions ou héritage plus difficiles. Vous copiez simplement et collez le code dans chaque endroit de manière à ce que vous changiez si vous changez du code, les modifications seront correctement collées partout sans que vous ayez à craindre de les suivre comme si vous aviez une copie à la main et collé.

Ainsi, utilisez des mélanges de chaîne le cas échéant, et il est probablement préférable de ne pas les utiliser s'il n'est pas nécessaire, mais il n'y a rien de vraiment mal avec les utiliser.


5 commentaires

J'ai trouvé que le seul moyen d'améliorer le problème du numéro de ligne était d'insérer les directives #line dans la source de mixage de chaîne. De cette façon, les erreurs sont généralement tombées d'environ le bon endroit; Fait déboguer une bibliothèque de liaison complète construite sur des mélanges de chaîne générées par CTFE moins un cauchemar complet et total.


Vous pouvez simplement écrire une fonction CTFE pour supprimer les nouvelles lignes, vous savez. ^^


@Feepingcreature lol. Mignon. Cela aiderait à la ligne dans le message d'erreur indiquant la ligne que la chaîne est mélangée ainsi que des messages d'erreur plus loin dans le fichier, mais cela ne vous aiderait pas à trouver l'erreur dans le mixin lui-même. Bien sûr, puisque vous ne savez même pas nécessairement ce que le code est mélangé à l'impression, sachant que le numéro de ligne de la ligne est mauvais ne vous aide pas nécessairement à vous aider. Je suppose que la morale de l'histoire est que les mélanges de chaîne qui fonctionnent sont formidables, mais les buggy peuvent être une douleur à réparer.


WeEll .. Point pris, mais surmonter principalement une fois que vous connaissez le mixin, vous pouvez simplement mettre les nouvelles lignes de retour et soustraire des numéros de ligne. :-)


Cependant, étant donné à la façon dont le mélange dans les chaînes tend à désordre les numéros de ligne d'erreurs pour le reste du fichier (même si le mixin est bien), il peut s'agir de la bonne pratique de mélanger les nouvelles lignes dans le mixin juste pour que les autres messages d'erreur sont sensibles.



1
votes

String Mixin est comme Goto: il doit être évité si possible et doit être utilisé partout où requis.


9 commentaires

Il y a une certaine vérité à cela, mais j'éviterais généralement le goto comme la peste alors que je serais tout à fait disposé à utiliser des mélanges à chaîne dans diverses circonstances. Maintenant, s'il y a de meilleures solutions que des mélanges à cordes, je vais certainement le prendre, mais je suis parfaitement disposé à mettre des mixines à chaîne dans mon code pendant que je vais penser dur et vraiment reconsidérer avant de mettre un goto dans mon code.


@Jonathan M Davis: Cela me semble que vous êtes plus réticent à utiliser goto que je suis. OTOH Il y a très peu de cas où vous devez utiliser goto dans d avec une pause étiquetée et continuer.


@BCS J'utiliserais essentiellement goto dans une langue à moins que je n'ai eu aucun autre choix pour obtenir la performance dont j'avais besoin. Je n'aime pas vraiment étiqueté continue ou étiqueté des pauses non plus, mais je serais prêt à les utiliser si cela a eu un bon sens dans une situation particulière. Mais tout droit aller? À peu près aucune chance de cela. Sauf si vous vraiment besoin de la performance, il y a toujours une meilleure façon. Alors, oui, on dirait que je suis plus réticent à utiliser goto que vous.


@Jonathan: Qu'est-ce qui ne va pas avec étiqueté continue / pauses? Comment sinon (en plus Goto) êtes-vous censé sortir d'une structure de contrôle imbriquée?


Oh, ils peuvent être assez utiles. Mais le code est généralement beaucoup plus propre s'il est écrit d'une manière qui ne nécessite pas de sauter comme ça. Je dirais que dans la plupart des cas, le code qui nécessite une poursuite ou une rupture étiquetée pourrait être réécrit de manière plus propre qui ne les nécessitant pas (et sans trucs comme des drapeaux laids indiquant que vous devriez simplement tomber hors de l'ensemble des boucles qui Vous êtes intitulé - étiqueté continue et les casserons sont certainement meilleurs que que sorte de code). Donc, je pense que la langue devrait les avoir, mais si votre code les utilise, il devrait être refactored si possible.


@Jonathan: @dsimcha: Le moyen le plus simple d'éviter les pauses étiquetées est d'envelopper la boucle extérieure dans une fonction et de faire un retour. OTOH (si votre chance) finit par être renversé vers la même chose. @Jonathan: Pourriez-vous donner un exemple de quel type de refactoring vous envisagez?


@Bcs, je devrais vraiment regarder des exemples spécifiques à dire - bien que j'ai refactorisé une partie d'une fonction d'une fonction. Beaucoup de fois, cela signifie simplement aller sur le problème légèrement différemment ou la rompre différemment. Personnellement, je rencontre rarement la nécessité de se briser à une boucle extérieure et, lorsque j'ai eu, j'ai généralement trouvé des moyens de refroidir le besoin. Mais il est assez peu fréquent que je n'ai pas de bons exemples de la tête.


Je l'ai rarement couru soit mais je n'ai jamais eu besoin de la rétrécir.


@BCS C'est plus un problème dans C ++ que d parce que vous devez utiliser une variable d'indicateur d'une sorte de type en C ++, car il n'y a pas d'étiqueté de continuer ou de casser en C ++. Je ne serais pas tout aussi préoccupé par le refactorisant en D comme en C ++, mais cela me dérangerait probablement assez pour le refroidir si je pouvais raisonnablement le faire.