Clases internas en Groovy

Acabo de toparme con un problema en Groovy. Tristemente la solución que todo mundo da en foros es simplemente "no lo hagas, es mejor si haces [cualquier otra solución]"; pero, qué tal si lo que necesitaba era esto?

Bueno y ¿cuál es el problema? Es simple: el soporte en clases internas tiene problemas con atributos heredados en la clase externa. Tiene solución, y es sencilla, pero me parece una leaky abstraction y honestamente la encontré por pura suerte, buscando maneras de darle vuelta al asunto.

El problema se da bajo estas circunstancias:

 

Este código truena, en tiempo de ejecución obviamente; se arroja una   que nos dice que no existe el campo   en la clase  . Es decir, está tratando de acceder a   directamente como un campo, pero no como un atributo (invocar el   generado).

Soluciones

Este problema tiene tres soluciones:

La más fea es marcar el atributo de la superclase como  , y con eso ya funciona el código. Tal vez se puede hacer, tal vez no, tal vez es inconveniente, etc.

La menos fea es que en la clase interna se invoque   en vez de simplemente  . Con eso funciona, pero pues se cae la cortinita; me refiero a que la ilusión de que los getters y setters funcionan de maravilla en Groovy es eso, una ilusión. Creo que esto es un problema en el compilador de Groovy, que no detecta los campos heredados para convertir ese   en la clase interna en una invocación a   y por eso la tengo que escribir yo directamente, rompiendo la abstracción de los atributos autogenerados en Groovy.

Otra que tampoco está tan mal pero no entiendo por qué hay que usar, es que en vez de simplemente  , escribir  . Sin embargo esto me resulta algo confuso, pues en Java no es necesario hacer eso bajo las mismas circunstancias.

En fin, una cosita más que le encuentro a este lenguaje que si bien es muy práctico, tiene varios detallitos (para mi al menos), principalmente por ser tan dinámico.

Lo grave de esto es que me lo topé ya que tenía bastante tiempo invertido en ese esquema de clase padre abstracta + subclase con clase interna; después de visitar varios foros de Groovy, todos dicen "no uses clases internas, mejor usa closures" y cosas por el estilo. Pero, y si ya tengo esto hecho? Obvio no iba a hacer un refactoring medio choncho simplemente para cambiar la clase interna por closures, afectando un montón de cosas más; por eso me puse a buscarle hasta encontrar estas alternativas que publico aquí, que espero le sirvan a alguien en el futuro.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Reporte

Lo bueno de Groovy es que sus devs están siempre al pendiente; en cuanto publiqué la liga a esto en twitter, uno de ellos me contactó para que levantara el reporte del bug. Y aquí está:

Imagen de arterzatij

:'( quiero llorar (que

:'( quiero llorar (que marica) pero esto sres es lo bonito de las comunidades :) sigamos por este camino...

Tal vez...

No sé si a lo mejor el uso de @Mixin te hubiera ayudado, y no tendrías que hacer un gran refactor. El problema/ventaja de Groovy es la forma en como resuelve las llamadas a los métodos(la excepción que te arroja es de tiempo de ejecución, y no de compilación ), como lo dije una vez, la gran ventaja de Groovy es su dinamismo, pero a veces es tan dinámico que aun cuando lo escribes mal, aún así funciona, no como debiera pero funciona.

En fin...