2009-10-23 8 views
6

Lamdbaj permite la definición de los cierres en el lenguaje Java, varios ejemplos se pueden encontrar heremecanismos de Java en uso en cierres lambdaj

Mi pregunta es con respecto a los mecanismos de Java subyacentes en el uso, por ejemplo, para definir el println cierre, se utiliza el siguiente código:

Closure println = closure(); 
{ of(System.out).println(var(String.class)); } 

Este cierre puede ser ejecutado posteriormente a través de:

println.apply("foobar"); 

Tengo curiosidad sobre qué mecanismos en Java permitirían que la llamada a of(...).println(...) se asocie con la instancia println.

Naturalmente, el código fuente de lambdaj está disponible para leer, pero esperaba una explicación de nivel ligeramente superior si alguien tiene una. Mis habilidades de reflexión llegan hasta un poco de introspección y ejecutan métodos dinámicamente.

+0

Me estoy perdiendo la "cierre" poco? Veo un método levantado, pero eso es todo. : -/ –

+1

En realidad, Lambdaj no admite cierres. Específicamente, no puede capturar variables del alcance adjunto. –

Respuesta

2

Bueno, of es presumiblemente un método static que se importa estáticamente por lo que se puede invocar sin el nombre de la clase adjunta. Espero que var sea el mismo. Ambos métodos tienen que regresar algún tipo que tienen los métodos llamados posteriormente:

public class Printable { 
    public void println(Var var); 
} 

public class Fac { 
    public static Printable of(Object o) { 
    return new Printable(o); 
    } 

    public static Var var(Class<?> clazz) { 
    return new Var(clazz); 
    } 

} 

De repente:

Fac.of(System.out).println(Fac.var(String.class)); 

es Java válido. El uso de las importaciones estáticas, ¡listo:

import static Fac.*; 

of(System.out).println(var(String.class)); 

Los entre llaves son, evidentemente válida Java como puede agregar estos en cualquier método para ayudar en la definición de un jabón de léxico. Este estilo de diseño de API se llama fluent y se muestra mejor en la biblioteca de pruebas JMock.

Por cierto, si esto supone introducir cierres en Java, es bastante ridículo: la sintaxis es insoportablemente horrible. Su ejemplo de E/S en realidad me hizo reír a carcajadas. Pruebe Scala!

EDITAR - los dos println llamadas están asociados Creo porque la primera secuencia de llamadas permite que la biblioteca para capturar las variables que ha pasado como parámetros. Estos probablemente se capturan en alguna estructura ThreadLocal. Cuando llamas a un método (también presumiblemente estático) println, la biblioteca está utilizando estos datos capturados para ejecutar el comportamiento en un momento posterior. También relacionado con las pruebas, el marco de prueba EasyMock utiliza un mecanismo similar (que utiliza proxies Java en segundo plano) para capturar los valores esperados.

+3

+1. Después de 3 años de C++, pensé que sabía sobre cierres feos, pero * Dios todopoderoso * ... –

+0

Gracias, de hecho, me he pasado a Scala la mayor parte de mi desarrollo activo ahora. Esto todavía me confunde, entiendo el elemento de importación estática, mi perplejidad es cómo la llamada a (...). Println (...) de alguna manera está asociada con la instancia 'println' definida antes de ella, en mi ejemplo de apertura . –

+0

OK - He editado mi respuesta, ya que creo que sé cómo esto está sucediendo. –

10

Soy Mario Fusco y soy el principal desarrollador de la biblioteca lambdaj.

Antes que nada me gustaría aclarar algo: lambdaj no pretende reemplazar ningún lenguaje funcional. Como dije la semana pasada en mi discurso en la Jarra de Zurich, si tiene la oportunidad de usar Scala, vaya y nunca mire hacia atrás.Aquí puede encontrar un resumen de mi discurso en el que se afirma claramente que:

http://ctpjava.blogspot.com/2009/10/lambdaj-new-trends-in-java.html

Soy un desarrollador feliz Scala también. Pero a veces simplemente estás obligado a desarrollar en Java (en mi experiencia, en el mundo real, alrededor del 80% de las veces no puedes elegir en qué idioma tienes que escribir tu código) y en este caso algunas de las características de lambdaj podrían ser útil (o eso espero) Solo quería traer a Java algunas características funcionales que están totalmente ausentes. Por supuesto, el resultado no es completamente satisfactorio debido principalmente a la limitación impuesta por Java.

En cuanto al mecanismo lambdaj interno, sí utiliza un ThreadLocal para lograr ese resultado. Si usted tiene otras preguntas, curiosidades o incluso mejores sugerencias y críticas constructivas sobre lambdaj tal vez usted podría estar interesado darse de alta en la lista de correo lambdaj aquí:

http://groups.google.com/group/lambdaj

adiós Mario