dimanche 27 février 2011

Safe monkey patching en javascript

Formellement, le monkey patching consiste à modifier et étendre à l'éxécution des éléments du code déjà produits ou faisant partis du noyau d'un langage.

Autrement dit, agir sur des éléments déjà définis sans modifier le source (notamment celui de l'interpréteur).

Plus prosaïquement, il s'agit le plus souvent d'ajouter une méthode à un type natif, de redéfinir une méthode existante, ou - quand le langage le permet, de modifier le comportement des opérateurs ('+', '-', '==', etc.).

Mais concrètement...

En ruby par exemple, la librairie 'Complex' ajoute les méthodes "im, image, real, polar, conjugate, ..." à la classe Numeric, ce qui permet de considérer n'importe quel nombre comme un complexe (en math l'ensemble des réels est compris dans l'ensemble des complexes).


En javascript, le monkey patching est fréquent sur les tableaux, qui manquent de méthodes utiles dans la plupart des implémentations :



Les avantages

Le principal avantage du monkey patching est de pouvoir modifier des éléments existants de façon 'transparente' pour les utilisateurs.

Une fois que la méthode filter à été ajoutée au prototype de Array, les developpeurs peuvent y faire appel comme s'il s'agissait d'une primitive du langage.

L'utilisation est plus naturelle que par l'ajout classique d'une fonction ou d'une classe:



Les inconvénients

Tout cela est bien joli, mais toucher à ce qui est déjà défini n'est-il pas un pas dangereux ? Je me souviens d'un déboggage javascript qui avait bien failli me rendre fou : quelqu'un avait modifier la methode call de plusieurs objets fonctions...

J'ai mis plusieurs heures à m'apercevoir que le problème ne venait pas de mon code, mais de cette redéfinition un peu cavalière. L'auteur de cette modification ne connaissait tout simplement pas le prototype Function.prototype.call.



De manière générale, le danger est de donner un comportement inattendu à une méthode existante, ou non conforme à une implémentation d'une future version du langage. Pour cette raison, certains bannissent tout simplement le monkey patching.

Le monkey patching sans risque

Dans cette article, nous allons voir plusieurs méthodes pour faire du monkey patching sans risque.

Methode servant de namespace

Une methode simple pour limiter les risques est d'attacher les méthodes du patch à la demande.

Pour garder l'esprit objet (et la possibilité de chainer les méthodes) on pourra monkey patcher à travers une unique méthode dont le nom aura peu de chance d'être utilisé (votre nom de domaine sans l'extension par exemple).



Les plus paranoïaques pourront utiliser une chaine de caractères avec des symbole pour diminuer encore les risques de collisions de noms:



Scoper le monkey patching

La méthode précédente fonctionne mais elle ne répond pas au problème complétement: Construire un espace dans lequel on puisse modifier le langage à sa guise, et en dehors duquel nos modifications ne soient pas prise en compte.

Moke code

Traduisons ça par du code, tel que nous souhaiterions qu'il fonctionne :

L'idée est d'utiliser une fonction anonyme pour servir d'espace d'application de nos patches.

Une implémentation possible



Cette implementation, somme toute basique, permet de patcher des objets instanciés aussi bien que des constructeurs. D'ailleurs une partie du code se sert d'un monkey patch !

Aucun commentaire:

Enregistrer un commentaire