Refactoring con Metaprogramacion
September 27th, 2006
Este articulo sobre metaprogramacion fue previamente publicado por Ola Bini
La metaprogramación reflexiva forma parte de la conciencia de los programadores desde hace tiempo. Se puede lograr en muchos lenguajes, de una manera u otra. Algunos lenguajes lo han adoptado mejor que otros, entre estos podemos destacar Lisp, SmallTalk, Python y Ruby. A partir de que Ruby se hizo más popular, la metaprogramación actualmente comienza a ser algo más comunente utilizado. La discusión sobre DSL’s (domain specific languages) esta asociada con la metaprogramación, implementar un DSL (en el mismo lenguaje, por supuesto) es muy difícil sin metaprogramación reflexiva.
Recientemente releí mi copia de Refactoring, y como es usual me asombré de cuán en tema estaba, y cuán fácil y útiles eran los trucos que describe. Pero, también empecé a pensar que faltaba algo. Refactoring esta orientado a la Programación Orientada a Objetos, pero fui más y más adelente en la Programación Orientada a Objetos, con DSL’s, metaprogramación reflexiva, instrospección, y extensiones Meta-class. Todo esto hace la base de POO mucho más poderosa. Esto es muy importante también cuando prototipamos pequeños sistemas. Encontré que escribiendo métodos de esa manera tenía que hacer mucho a mano, y en la siguiente instancia achique mi código lo más que pude para que quede claro y fácil.
¿De qué es este blog entonces? Propongo que sea un catálogo de Refactorings con Metaprogramación. No estoy diciendo que tienen que hacerlo, para nada, pero es algo bueno para conocer. Puede ser como un wiki en algun lugar, donde alguno de nuestros iluminados de la metaprogramación podrian escribir sobre sus experiencias. DHH? _why? Weirich? Dave Thomas?
Igualmente, solo para mostrar de que clase de refactoring estoy hablando, voy a dar algun tipo de ejemplo artificial. Esto es más o menos lo que sería una implementación de un mock o algo similar. Algunas llamadas al log, y bastante repetición.
Les presento el Extract Code Template Metarefactoring. El primer paso es tomar todos los nombres de los métodos que deberían ser manejados y ponerlos en una lista como ésta:
Entonces iteramos sobre estas definiciones, y proveemos estructuras vacías para cada uno de esta forma:
Entonces tenemos que cambiar la lista a un hash, haciendo que cada nombre de método apunte al correspondiente a llamar en cada caso. Algo así:
Cuando esto está terminado, tenemos que agregar la parte del método principal el cual no puede ser extraido de la misma manera, así que lo haremos con un Proc:
El siguiente paso es iterar sobre los nombres de los métodos y valores, y definir el contenido de los mismos. Entondes quitamos los métodos originales. Finalmente, nuestro código quedaría de la siguiente forma:
Ahora, en este caso, no estoy seguro si haría este refactoring. Esto sirve más como un ejemplo de que tipos de refactorings me gustaria encontrar en un catálogo como este. Refactorings como Extraer DSL (Extract DSL), Crear clases dinámicamente (Create Class Dynamically), Extender desde una clase Anónima (Extend From Anonymous Class) y otros, son algunos ejemplos de los que realmente creo pueden ser utiles en la programacion de hoy en dia.





Leave a Reply