Administración del Conocimiento – UML Simulation

Ventajas de la Reflexión en Programación – Meta-programación Simple

Posted in POO by smalltalkuy on enero 26, 2012

Sistema

Se está construyendo un sistema el cual debido a su naturaleza fuera de lo común tiene cerca de 200 métodos que devuelven un String simplemente.

En la siguiente imagen se muestra 1 de estos métodos, como el sistema está relacionado con el PMI, el texto que se muestra es copyright  © de PMI.org.

Problema

Por cada uno de estos 200 métodos hay que crear otro método derivado que replique un mismo patrón, por lo hay que crear 200 nuevos métodos. Es un trabajo que tedioso que lleva tiempo y es propenso a errores.  Aquí es donde nos “salva” la REFLEXIÓN y la META PROGRAMACIÓN, en este caso es bastante sencilla.

Como quedaría el método luego de aplicar el patrón a mano:

Habría que aplicar el mismo patrón para otros 199 metodos y así sucesivamente. Con este nuevo método #changeRequestsNew tendría una instancia con la descripción que devuelve el método original (#changeRequests) que es solamente texto, que es justamente lo que quiero para este método y el resto.

Patrón

1. nombreNuevoMetodo := Nombre del método actual  + ‘New’. En este caso: changeRequests‘New’ = changeRequestsNew

2. El argumento que se pasa al mensaje #name:  debe ser el nombre del método actual, pero separado por un espacio y cada palabra en mayúsculas.  En este caso es:

name: ‘Change Requests’ – recordar el nombre del método actual (self) es #changeRequests

3. El argumento que se pasa al mensaje #description:  debe  ser una llamada al método actual que devuelve un String. En este caso es:

description: self changeRequests. – la descripción queda con el String del método original.

Este patrón debe aplicarse a 199 métodos más…

Solución

La solución me tomo unos 5 minutos ! y consiste en implementar un método en la clase CompiledMethod. En Smalltalk cada vez que creo un método se crea una instancia de esta clase CompiledMethod, y esta clase es editable y modificable como cualquier otra.

La variable [selector] del método actual (#changeRequests) se concatena con ‘New‘ para formar el selector (nombre) del nuevo método a ser creado.  Este nombre se almacena en la variable temporal [newSelector] como un símbolo #asSymbol (es una clase especial de String).

Ahora en la variable temporal [pmpName] formo el nombre según las reglas. La primera letra la paso a mayúscula (first asUppercase asString) y luego proceso el resto.

Ahora proceso todo menos la primera letra (c) [hangeRequests]. Si esta en minúscula copio y si esta en mayúscula agrego un espacio en blanco y copio. Guardo el resultado de la iteración en la temporal [pmpName].

Ahora creo un template para compilar el método en la variable [newMethod]. Uso el nombre del nuevo método y uso el selector actual (nombre actual) para crear la llamada (description: self’, selector,). Y por último compilo el template [newMethod] en la clase del método actual (methodClass compile: newMethod).

Ahora solamente cada vez que quiero crear uno de estos 200 métodos simplemente le envio el mensaje #compileMethodStringForPMPNewDocument y me crea el derivado.

En un principio pensé hacer esto con el Code Rewriter pero después opte por implementar un método en CompiledMethod.

El Code Rewriter es una herramienta muy poderosa que sirve para hacer transformaciones masivas de código de forma segura, basicamente suplante un AST por otro AST equivalente (mismo comportamiento) pero más óptimo.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: