¿Por que esto no funciona este GString como lo espero?

Se me ocurrío, no sé ni como probar la creación de un GString, pero no se evalua como yo lo espero, ¿alguien sabe por que?

Mi código es este:

 

Imprime:
 

Si en vez de eso escribo:

 

Funciona bien. Me reacción inicial fue que el string resultante por array.join no es un GString sino un String normal, es por eso que después lo cree con el "plus".

Medio deduzco la razón por la cual no funciona pero me gustaría saber de cierto.

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

sí es GString

Pero lo que quieres hacer no funciona porque no se evalúan de manera mágica. Cuando lo creas como en el segundo ejemplo, inline, se evalúa en el contexto donde lo estás creando. Pero en tu primer ejemplo lo estás generando de manera dinámica. Para que ese GString se evalúe, invoca  . Con eso creas el template y le das los valores que debe reemplazar, como un mapa:

 

Supuse que se evaluaría hasta

Supuse que se evaluaría hasta entonces por este parrafo:"GString can involve lazy evaluation so it's not until the toString() method is invoked that the GString is evaluated" que encontré aquí.

Entiendo que el ejemplo que pones funciona, pero ya no sería usar GStrings, sino el template que usa las expresiones GString o JSP

Lo siguiente sigue funcionando:

 

Da:

 

O será que usa eso internamente?? Interesante :)

Imagen de ezamudio

yo lo usé

No sé si sea la manera óptima, yo lo usé para presentar mensajes con parámetros en una aplicación (bueno realmente era mandar un mail; leo el texto y lo paso por el template junto con unos objetos para que se reemplacen todas las variables en el texto por los datos y luego se envia el correo).

Imagen de bferro

Call By Name y Call By Value

Son varias las estrategias de evaluación de los argumentos que se pasan a las funciones. Dos de esas estrategias en la programación funcional son Call By Value y Call By Name.

En la estrategia de Call By Value el argumento (cualquier expresión) es evaluado antes de ser pasado a la función. Cuando eso sucede, el valor que resulta de la evaluación es una hoja del árbol y no se evalúa nuevamente.

Con la estrategia Call By Name, la expresión que se pasa como argumento no es evaluada hasta tanto no sea usada dentro del cuerpo de la función.

Groovy no soporta la estrategia Call By Name. Para lograr esto, combina la estrategia de Call By Value con alguna clausura dentro del cuerpo de la función, que es lo que precisamente está sucediendo en el ejemplo que han estado discutiendo: crear un bloque de texto con un binding asociado, en este caso a la variable name que es evaluada mediante Call By Value antes de que comience a ejecutarse la función test.

Reescribo el código:
 

Al ejecutarlo obtengo:

 

Scala soporta Call By Name y Call By Value. La sintaxis de Call By Name omite los paréntesis que normalmente acompañan a los argumentos de la función