Or, si à l’époque la transition de atoum\
vers mageekguy\atoum
a été facile, elle n’était plus aussi simple presque deux ans après.
Tout d’abord, le nombre de fichiers du projet avait grandement augmenté, et de plus l’espace de nom apparaît massivement dans son code, tant au niveau de la définition des classes que dans mes tests, et aussi bien sous la forme d’une chaîne de caractères que sous la forme d’une instruction PHP.
Malgré l’existence de plus de 16 000 assertions réparties dans presque 150 classes de test et plus de 1000 méthodes, le risque était donc grand d’introduire un bug dans le code en effectuant la modification nécessaire.
De plus, depuis la publication de atoum, j’attache une grande importance au fait d’assurer dans la mesure du possible et du raisonnable une rétrocompatibilité maximum.
Je devais donc trouver une solution pour que ce changement d’espace de nom ait un impact minimum, voire nul, sur les utilisateurs du projet.
Et j’ai eu l’idée d’utiliser le mécanisme d’autochargement de classe d’atoum pour y parvenir.
En effet, si j’avais décidé de suivre la règle de nommage préconisée par PSR-0 concernant les classes d’un projet, je n’ai pas pour autant mis en place un mécanisme d’autochargement compatible avec cette dernière.
J’étais donc libre de le modifier pour lui permettre de créer à la volée lors de l’exécution des tests les classes nécessaires dans l’espace de nom atoum\ afin de remplacer celles définies dans l’espace de nom mageekguy\atoum.
J’ai donc introduit la notion d’alias d’espace de nom dans atoum, ce qui m’a permis de définir l’alias atoum\ pour l’espace de nom mageekguy\atoum.
Ainsi, lorsqu’une classe est requise dans le nouvel espace de nom, comme par exemple atoum\test
, atoum commence par résoudre l’alias correspondant et transforme donc le nom de la classe demandée en mageekguy\atoum\test
.
Il est alors à même de localiser le fichier correspondant, de l’inclure et de créer, cette fois au niveau du moteur de PHP, l’alias correspondant à l’aide de la fonction class_alias()
.
Ainsi, une même classe peut exister sous deux noms différents sans le moindre problème et non seulement les utilisateurs d’atoum ne sont pas obligés de modifier leurs tests pour utiliser le nouvel espace de nom, mais en plus, ils sont libres d’utiliser celui de leur choix.
Et cerise sur le gâteau, l’impact sur les performances est négligeable.
De plus, le jour ou nous aurons le temps, nous pourrons effectivement modifier dans le code et les tests du projet l’espace de nom mageekguy\atoum en atoum\, et nous n’aurons plus ensuite à faire de mageekguy\atoum un alias de atoum\ afin de conserver la rétrocompatibilité.
Pour l’instant, le seul inconvénient que j’ai pu trouver à cette solution est qu’elle n’est pas valable si des classes sont chargées explicitement par le développeur via include
ou require
mais j’aime à penser que cette pratique est plus que marginale et de toute façon, même dans ce cas, le code reste parfaitement fonctionnel si l’espace de nom mageekguy\atoum
est utilisé.
Et rétrospectivement, je suis très heureux de ne pas avoir suivi PSR-0 jusqu'au bout et d'avoir ainsi conservé la maîtrise totale du mécanisme de chargement de classe de atoum.
une réaction
1 De mnapoli - 17/01/2013, 14:35
Je suis pas vraiment conquis. Gros bidouillage, j'aurais pensé que la "grosse migration" aurait été faite lors du passage du package de mageekguy/atoum vers atoum/atoum (ce qui aura de toute façon nécessité une action côté utilisateurs : changement de dépendance). À la limite, l'inverse aurait été plus adapté, à savoir "atoum" devient le "vrai" namespace et "mageekguy/atoum" est un alias pour garantir la rétrocompatibilité.
Le principal problème c'est qu'une bonne majorité des développeurs n'utilisent pas forcément vim mais un IDE qui va autocompléter les classes (et créer des warnings pour les classes qui n'existent pas). Peu de chance de passer à "atoum\" dans ces conditions si c'est juste un alias.
En tout cas je suis d'accord avec toi sur une chose, cette manie "d'obliger" d'avoir un vendor name pour respecter PSR-0 est bof bof.