tps-2014-c1-tp3-metaprogramacion
Aclaraciones iniciales
En este TP vamos a desarrollar una librería o framework, es decir, una herramienta reutilizable independiente del dominio. El objetivo es que esa herramienta pueda ser utilizada en muchos dominios. Por eso es importante que el código específico de la herramienta no tenga relaciones con el dominio.
Todos los dominios que se citan a continuación son sólo ejemplos. Pueden utilizar los ejemplos para probar su herramienta, pero la herramienta no puede ser dependiente del ejemplo.
Por eso su entrega debe consistir de tres partes:
- Código específico de la herramienta
- Un dominio que se utilizará para las pruebas
- Tests
Requerimientos
1 - Trait GenericEquals
Programar un traits de nombre GenericEquals
con los siguientes métodos:
* Requiere el método #keyProperties
, esperando que le entregen una lista de Strings, que representan un conjunto de nombres de variables de instancia.
* Provee el método #=
, que tomando la lista de variables de #keyProperties
determina si el objeto receptor es igual al recibido por parámetro.
Por ejemplo usado en la clase Soldado, definida así:
Object subclass: #Soldado
uses: GenericEquals
instVarNames: 'posicion puntosDeVida'
...
y el método
>> keyProperties
^ #(puntosDeVida)
La siguiente porción de código debería evaluarse como verdadera:
a := Soldado new posicion: 100@100; puntosDeVida: 100.
b := Soldado new Posicion: 200@200; puntosDeVida: 100.
a = b.
En cambio, si modificamos el método #keyProperties de la siguiente manera:
>> keyProperties
^ #(posicion puntosDeVida)
La misma porción de código se evaluaría como falsa, dado que los dos Soldados tienen la misma cantidad de puntosDeVida pero no la misma posición.
2 - Trait GenericPrint
Siguiendo el mismo esquema del ejercicio anterior, programar el trait GenericToString
, con los métodos:
- Requiere
#keyProperties
- Provee el
#printOn:
basándose en#keyProperties
Luego la siguiente porción de código:
Soldado new posicion: 100@100; puntosDeVida: 100.
Al evaluarse deberían imprimir Soldado(posicion = 100@100, puntosDeVida: 100)
, considerando la segunda versión de #keyProperties.
3 - Refactor SimpleRenameProperty
Programar la clase RenameProperty que sea capaz de renombrar una variable de instancia y sus accessors consistentemente.
Por ejemplo si nuestra clase soldado tiene además de la variable posicion
dos métodos:
>> posicion
^ posicion
>> posicion: nuevaPosicion
posicion := nuevaPosicion
Se busca que renombre tanto la variable de instancia como los dos métodos posicion
y posicion:
.
**Nota: **Para simplificar, podemos considerar que ni la variable ni los métodos tienen referencias y por lo tanto con que el rename sea consistente es suficiente y no es necesario mirar dentro del código.
Requerimientos Bonus
1 - Refactor FullRenameProperty
Al refactor anterior agregarle la capacidad de buscar referencias a la variable y a los métodos renombrados, acotándolo al package.
2 - Interfaz de usuario
Implementar alguno de los refactors de RenameProperty dentro del Refactoring Browser