Variant Is Out
La semaine dernière je parlais de la gestion des erreurs en PHP et comment mieux faire.
De plus en plus je suis lassé de créer mes ValueObjets ou d’utiliser les Results de GrahamCampbell. Non pas que ce derniers soient mauvais, loin de là, mais plutôt que je n’apprécie pas tellement la DX qu’il propose.
Et puis on a tous nos petites habitudes. Ca ne convient pas, tout simplement à mes goûts. Quand j’ai le choix d’utiliser autre chose, j’en profite.
Ces temps-ci sur mes projets perso je me retrouve à créer beaucoup de ces objets de transition, pour plus de type-safety dans mon code. Quitte à utiliser une langage objet, autant ne pas avoir que les inconvénients…
Pourtant créer ces objets de transition, c’est essentiel pour un code fiable. Sinon je me retrouve à tout passer dans des objets avec des clefs indicées.
Et puis on s’y perd, on a pas de type-safety
.
Alors qu’en Gleam
je peux créer mes types très simplement, les utiliser, et être sûr de ce que je fais.
Ca fonctionne, c’est rapide, je ne réflechis qu’à ma logique métier (même si je deteste ce terme).
C’est de ce constat qu’est né variant
, un générateur de variants.
Je veux mes types personnalisés, rapidement et sans trop de contrainte. Je veux mes result
types.
Une génération statique
Le plus simple était de faire une génération statique. On déclare ce que l’on souhaite dans un fichier avec l’extension .variant
et on lance le générateur.
Il crée les fichiers, c’est fini.
Créer ce type de structures à la volée, dans le code, c’est à mon avis plus de problèmes que d’autre chose:
- Le LSP est dans les choux.
- Plus de travail pour PHP.
- Potentiellement des redéfitions qui cassent des parties sans qu’on ne le sache.
Un fichier déposé dans un dossier, et ça génère là où on l’a souhaité. Ce n’est pas parfait mais ça à le mérite de fonctionner et de ne pas interferer dans mon travail.
Trois instructions, et c’est tout
Pour le moment, variant
est construit autour de mes besoins, et je n’ai besoin que de 3 instructions:
type
, pour un groupement de types autour d’une interfacerecord
, pour un type seul. Sous le capot,type
construit desrecord
qui implémentent son interface.results
, pour avoir un type de résultat qui me retourne les types possibles, potentiellement d’untype
, et une valeur deok
.
Peut-être qu’on peut faire plus, ou mieux, je ne sais pas. Pour l’instant cela me convient.
Immutable au maximum
Chaque code généré produit une classe avec des champs readonly
. Impossible de modifier une valeur sans devoir la cloner.
Cela permet d’avoir de véritable ValueObject
qui passent les données.
Encore une fois, c’est un design que j’apprécie. On peut fortement remettre en question ce choix, mais il me convient pour l’instant.
C’est disponble maintenant sur Github/composer
Ici : https://github.com/AsymetricData/variant
Vous pouvez essayer en faisant un :
composer require cedriccourteau/variant --dev
Vous ajoutez un fichier mestypes.variant
là où vous souhaitez gérérer ces types, avec par exemple
record MonRecordTest(string param, int val)
vous lancez :
php ./vendor/bin/variant
Et voilà, vous avez une classe MonRecordTest
avec son constructeur de généré.
Par défaut, pour générer à nouveau vos variants, il faut relancer la commander avec le flag --force
pour écrire sur les anciennes générations.