@goldbergg :
Avec DMD 2.080.1 (un compilateur D), je viens de faire le test suivant :
Je crée un fichier "example.foo" qui contient la chaîne "unNomDeStructure".
Dans le même dossier, je crée un fichier "main.d" avec le code suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import std.ascii : toUpper;
import std.stdio : writeln;
void main() {
UnNomDeStructure var;
var.aMember = 5;
writeln("var.aMember == ", var.aMember);
}
mixin(codeOfStructWithUpperCaseFirstLetter(import("example.foo")));
string codeOfStructWithUpperCaseFirstLetter(string input) {
assert(input.length > 0);
char[] structName = input.dup;
structName[0] = toUpper(input[0]);
char[] result =
"struct " ~ structName ~ " {\n" ~
"int aMember;\n" ~
"}";
return result.idup;
} |
Le code charge le fichier "example.foo" et passe la chaîne correspondante à codeOfStructWithUpperCaseFirstLetter qui retourne le code d'une structure dont le nom ("UnNomDeStructure") est égal à la chaîne en paramètre, mais en remplaçant la première lettre par une majuscule. mixin "imprime" le code de cette structure.
Cela définit une structure UnNomDeStructure, que je peux utiliser dans main().
En ligne de commande, si je tape « dmd -J"." main.d », cela compile bien et crée un exécutable "main.exe" dont l'exécution affiche « var.aMember == 5 » dans la sortie standard.
L'option -J indique une adresse de dossier dans lequel chercher quand on fait import(adresseRelativeDeFichier).
Si je remplace le contenu de "example.foo" par "unNomDeStructureD" et que j'essaie de recompiler, le compilateur m'affiche :
main.d(5): Error: undefined identifier UnNomDeStructure, did you mean UnNomDeStructureD?
Si je remets "example.foo" comme avant mais si, dans codeOfStructWithUpperCaseFirstLetter, je remplace la chaîne "int aMember;\n" par "int someMember;\n", le compilateur ne sera pas content non plus :
1 2
| main.d(6): Error: no property aMember for type UnNomDeStructure
main.d(7): Error: no property aMember for type UnNomDeStructure |
Donc le chargement du fichier "example.foo" et l'exécution de codeOfStructWithUpperCaseFirstLetter se passent bien à la compilation.
Remarque : Le langage D est assez permissif sur l'ordre des déclarations dans un module. Alors, j'ai pu utiliser UnNomDeStructure dès la ligne 5 avant de définir cette structure, à la ligne 10 avec mixin. De même, j'ai pu utiliser codeOfStructWithUpperCaseFirstLetter à la ligne 10 avant de la définir, à la ligne 12.

Envoyé par
Marco46

Envoyé par
Uther
Et non une Url, ça n'est pas forcément une string. Tu peux très bien avoir un objet qui encapsule une URL par exemple pour apporter des garanties sur sa validité.
Tu peux mais c'est de l'overkill. Tu as seulement besoin d'une fonction de validation.
L'avantage d'une classe Url qui encapsule une URL, qui a pour invariant de classe que l'URL encapsulée est bien formée et dont le constructeur et les mutateurs s'assurent que l'invariant de classe est respecté, c'est que, une fois que l'objet est construit, on sait que l'URL contenue est valide.
Du coup, avec du typage statique, quand une fonction prend en paramètre un objet de type Url, on a la garantie que l'URL est bien formée. Sinon, l'objet n'aurait pas réussi à se construire et ne serait pas arrivé en paramètre. Donc on sait qu'on n'a pas besoin d'appeler la fonction qui vérifie si l'URL est bien formée.
Dans ton cas, concrètement, si tu as des fonctions qui parsent des URL, cela te permettra d'éviter d'écrire des tests unitaires inutiles dans lesquels tu passes à ces fonctions des URL mal formées pour voir si elles signalent bien une erreur : tu ne pourras pas leur passer des URL mal formées, puisque le constructeur de la classe Url t'en empêchera.
Partager