2011-12-21 8 views
10

Podría alguien desmitificar este código, que es parte del ejemplo zentasks en el marco PLAY20. Tengo curiosidad de cómo funciona esto, con la certeza de que soy nuevo en Scala de Java, por lo que son difíciles de entender muchas cosas.Código Scala desmitificar

def IsAuthenticated(f: => String => Request[AnyContent] => Result) = 
    Security.Authenticated(username, onUnauthorized) { user => 
    Action(request => f(user)(request)) 
    } 
+0

¿Hay alguna manera de representar esto usando la sintaxis de Java, sé que no es lo mismo pero podría ayudarme a entender la firma del método. Estoy teniendo dificultades con el orden de las operaciones aquí. – chiappone

Respuesta

16

Tiene que dividir la firma un poco. f es una función que toma una cadena que aún no es computada-=> String y devuelve otra función que acepta un Request[AnyContent] y devuelve un resultado.

La llamada Security.Authenticated acepta dos listas de parámetros. Uno que tiene username y onUnauthorized. El segundo toma una función que acepta al usuario y devuelve una acción.

El método Action.apply acepta una función Request[AnyContent] => Result

así, el f se llama en la moda 'curry'. Esa es la primera función que se llama, y ​​luego la función resultante se usa inmediatamente f(user)(request).

Aquí es lo mismo desazucaradas (al menos, lo mejor que pueda) y feo:

def isAuthenticated(f: => String => Request[AnyContent] => Result) = 
    Security.Authenticated(username, onUnauthorized) { user: String => 
    Action.apply { request: Request[AnyContent] => 
     val hiddenTmp: Request[AnyContent] => Result = f(user) 
     hiddenTemp.apply(request) 
    } 
    } 

Se puede ver que el compilador está haciendo un poco de trabajo de eliminación de anotaciones de tipo. Con suerte, eso ayuda a explicar cómo se desagrupa en scala cruda. Esencialmente, la función tiene mucha composición funcional.

2

primer lugar una guía de usuario a mi respuesta: Voy a utilizar cursiva para indicar una función que se utiliza sin ser nombrado explícitamente (ver anonymous functions).

IsAuthenticated es un método que toma como parámetro un argumento f.

f es una función que toma Y como un parámetro y produce una instancia de Resultado

Y es una función que toma Z como un parámetro y produce una instancia de Solicitud [AnyContent]

Z es una función que no toma parámetros y devuelve una cadena

IsAuthenticated llama Security.Authentic ated, pasando nombre de usuario y onUnauthorized (una función para llamar cuando el usuario no está autorizado para realizar la acción solicitada).

no estoy del todo seguro de lo que está pasando allá de mí mismo aquí no soy muy buena con la que Scala todavía- pero mi suposición es que Security.Authenticated es una clase de caso, y la siguiente es equivalente a la subclasificación y la adición de un constructor en java:

{ 
    Action(request => f(user)(request)) 
} 

Si que gran parte de mi suposición es correcta, entonces la acción (que es un método de Security.Authenticated) se está llamando, pasando como argumento un un.

A es una función que toma un objeto Request (estoy adivinando este nombre de clase) y produce un resultado. El uso del resultado está implícito aquí porque la implementación de A es una llamada a f.

Así que cuando se instancia la subclase de Security.Authenticated, se invoca Action, que autentica al usuario para alguna acción (especificada como String) y luego, si el usuario se autentica, devuelve f (el parámetro original) que es presumiblemente llamado por Acción (después de la autenticación antes mencionada). Esta llamada a f devuelve un resultado, que también es una función. El resultado finalmente se llama con la solicitud (que se pasó a A) como parámetro.

Cuestiones relacionadas