Lo + Leído
Eventos destacados
Artículos para tus primeros pasos
Si estás empezando a introducirte en el mundo de Groovy y Grails, no te pierdas nuestros artículos básicos:
- Introducción a Groovy, parte 1 (Andrés Almiray)
- Introducción a Groovy, parte 2 (Andrés Almiray)
- Introducción a Groovy, parte 3 (Andrés Almiray)
- Introducción a Grails (Material Seminario ImaginaWorks)
Los protagonistas te cuentan de qué van los proyectos más importantes del mundo Groovy:
Groovy: primeros pasos
Evaluación de GStrings a la carta
Pablo Riesgo - jueves 10/07/2008Hola,
Quiero crear un GString del estilo "hola ${variableMundo}" pero de tal manera que variableMundo no sea evaluada al declararla, si no que pueda ser controlada con un método del tipo GString.evaluate() o .toString()
El código sería parecido al siguiente, y este da un error en la declaracion del GString por no encontrar la variable para evaluarla.
class HolaMundo {
static def holaMundo = "hola ${variableMundo}"
statiic def diHolaMundo (String variableMundo)
{
// esta es la instruccion ficticia
println holaMundo.evaluate()
}
}
Si alguien tiene idea de como hacerlo o sabe algo sobre le tema, agradecería que me echara una mano.
Un saludo.
Re: Evaluación de GStrings a la carta
Pablo Riesgo - lunes 14/07/2008Hola Nacho.
De entrada gracias por responder. Con el ejemplo que puse intente simplificar el problema para hacerlo mas sencillo e ir al grano.
Sin embargo, lo que realmente necesito es poder evaluar un GString en tiempo de ejecución.
Voy a tratar de explicar como surgió esta necesidad:
Tengo una clase con sus respectivos métodos que devuelven código SMIL, el cúal mezcla unos videos e introduce bloques de texto sobre estos. Estos bloques de texto los he introducido en una variable map para aislar estos bloques de texto de la programación en SMIL
static def mensajes = [
smil1:[titulo:"Titulo 1", cuerpo:"Cuerpo 1"],
smil2:[titulo:"Titulo 2", cuerpo:"Cuerpo 2"]
]
Pero en estos bloques de texto quiero introducir valores pasados como parámetro a los métodos, de manera que:
static def mensajes = [
smil1:[titulo:"Titulo 1: ${usuario}", cuerpo:"Cuerpo 1"],
smil2:[titulo:"Titulo 2: ${usuario}", cuerpo:"Cuerpo 2"]
]
static metodo1 (String usuario)
{
return """<!-- codigo SMIL -->
<!-- bloque de texto -->
${mensajes.smil1.titulo}
<!-- bloque de texto -->
${mensajes.smil1.cuerpo}
<!-- fin codigo SMIL -->"""
}
Este código da un error al compilar por la introducción de la variable sin declarar usuario dentro de mensajes.
Por supuesto, siempre puedo meter ${usuario} a parte dentro del método pero solo queria saber si era posible de alguna manera para conseguir mantener la separación entre mensajes de texto y logica SMIL.
Espero que lo que acabo de escribir no sea incompresible :) y otra vez gracias de antemano.
Un saludo,
Pablo.
Re: Evaluación de GStrings a la carta
srcarro - viernes 18/07/2008Me da la sensación que estás intentando complicarlo demasiado. No soy un master del GString
(ya quisiese yo...), pero es posible que para lo que necesitas puedas tirar del "obsoleto"
Java y su java.text.MessageFormat. Vamos, algo así como:
------------------------------------------
class Clase {
static mensajes = [
smil1:[titulo:"Titulo 1: {0}", cuerpo:"Cuerpo 1"],
smil2:[titulo:"Titulo 2: {0}", cuerpo:"Cuerpo 2"]
]
static fmt(String msg, String valor) {
java.text.MessageFormat.format(msg, valor)
}
static metodo(String usuario) {
return """<!-- codigo SMIL -->
<!-- bloque de texto -->
${fmt(mensajes.smil1.titulo,usuario)}
<!-- bloque de texto -->
${fmt(mensajes.smil1.cuerpo,usuario)}
<!-- fin codigo SMIL -->"""
}
}
println Clase.metodo("luis")
------------------------------------------
He intentado montar algo parecido a lo que tú pretendes: como no tenemos la variable
'usuario', he creado otra, de trabajo, 'usuarioInterno'. Sin embargo, una vez creado
el GString, modificar el valor de dicha variable interna no tiene ningún efecto. Me
da a mi que el hecho de que las Cadenas sean inmutables en Java tiene algo que ver:
------------------------------------------
class Clase {
static def usuarioInterno = "pepe"
static def mensajes = [
smil1:[titulo:"Titulo 1: ${usuarioInterno}", cuerpo:"Cuerpo 1"],
smil2:[titulo:"Titulo 2: ${usuarioInterno}", cuerpo:"Cuerpo 2"]
]
static metodo(String usuario) {
usuarioInterno = usuario
return """<!-- codigo SMIL -->
<!-- bloque de texto -->
${mensajes.smil1.titulo} ${usuarioInterno}
<!-- bloque de texto -->
${mensajes.smil1.cuerpo}
<!-- fin codigo SMIL -->"""
}
}
Clase.metodo("Luisito") // Como si pasas 'jaimito', lo mismo da...
------------------------------------------
Es posible que, utilizando un objeto algo más dinámico para 'usuarioInterno', se pueda
conseguir algo...
Por último, he montado algo con closures. Mi escasa experiencia en Groovy no me permite
asurarlo, pero creo que el rendimiento de esto no es excesivamente bueno. Ahora, eso si,
es casi casi lo que querías:
------------------------------------------
def closMsgs = {usuario ->
static def mensajes = [
smil1:[titulo:"Titulo 1: ${usuario}", cuerpo:"Cuerpo 1"],
smil2:[titulo:"Titulo 2: ${usuario}", cuerpo:"Cuerpo 2"]
]
return mensajes
}
println closMsgs('pepe').smil1.titulo
println closMsgs('paco').smil1.titulo
------------------------------------------
Un saludo,
Enrique
Re: Evaluación de GStrings a la carta
GreenEyed - domingo 20/07/2008Hola,
Justamente hace unos dias estuve mirandome eso para poder hacer unos logs en los cuales pudiera pasar el formato dinamicamente añadiendo variables por nombre y no por orden, como hace Java. La buena noticia es que al final lo conseguí :)
La cosa acabó así:
messagePattern = .... // Yo lo leo de un fichero de propiedades, pero en fin: un String, que no un GString todavia para que no se ejecute.
def binding = ["usuario": variableUsuario, "otraVariable": otraVariable... ] // Aqui definimos las variables que vamos a usar para la "sustitucion"
// Se crea un template a partir del texto y el binding usando el SimpleTemplateEngine
SimpleTemplateEngine engine = new SimpleTemplateEngine()
def template = engine.createTemplate(messagePattern).make(binding)
// Obtenemos el valor con un simple toString
mensaje = template.toString()
Y voilà. Lo encontré en un artículo de IBM AlphaWorks perdido.
Saludos
Re: Evaluación de GStrings a la carta
Pablo Riesgo - jueves 24/07/2008Hola,
Muchas gracias por vuestra ayuda, acabo de leer las soluciones que proponéis.
La solución del closure, Enrique, era mas o menos lo que tenía en la punta de los dedos y no me salía, voy a ver que tal va en cuanto a rendimiento y tal.
Respecto a la última solución por supuesto ni se me había pasado por la cabeza, es una pena que no sea mas accesible desde un GString. Me podrías pasar la URL del articulo del que hablas.
Un saludo,
Pablo.
Re: Evaluación de GStrings a la carta
GreenEyed - domingo 10/08/2008Hola,
Perdona el retraso pero la verdad es que no frecuento mucho estos foros :).
El artículo donde lo encontré es este:
http://www.ibm.com/developerworks/java/library/j-pg02155/index.html
y buscándolo encontré también este:
http://www.javabeat.net/articles/63-templates-in-groovy-2.html
A ver si algo te sirve.
S!
Un momento...
Re: Evaluación de GStrings a la carta
Nacho - jueves 10/07/2008Hola Pablo,
dentro de un bloque ${} puedes poner código Groovy arbitrario, incluyendo llamadas a funciones, así que puedes hacer algo así:
def variable = "Pablo"
def holaMundo = "hola ${diHolaMundo(variable)}"
Saludos,