2011-12-21 12 views
10

Qualcuno potrebbe demistificare questo codice che fa parte dell'esempio zentasks nel framework Play20. Sono curioso di sapere come funziona, dato che sono nuovo di Scala di Java, quindi molte cose sono difficili da comprendere.Scala codice demystify

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

C'è un modo per rappresentarlo usando la sintassi java, so che non è lo stesso ma potrebbe aiutarmi a capire la firma del metodo. Sto attraversando un periodo difficile con l'ordine delle operazioni qui. – chiappone

risposta

16

È necessario dividere un po 'la firma. f è una funzione che accetta una stringa non ancora calcolata => String e restituisce un'altra funzione che accetta uno Request[AnyContent] e restituisce un risultato.

La chiamata Security.Authenticated accetta due elenchi di parametri. Uno che ha username e onUnauthorized. Il secondo accetta una funzione che accetta l'utente e restituisce un'azione.

Procedimento Action.apply accetta una funzione Request[AnyContent] => Result

così, la f è chiamato in modo 'curry'. Questa è la prima funzione chiamata, e quindi la funzione risultante viene immediatamente utilizzata f(user)(request).

Ecco la stessa cosa private degli zuccheri (per lo meno, come meglio posso) e brutto:

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) 
    } 
    } 

Potete vedere il compilatore sta facendo un po 'di lavoro di rimuovere le annotazioni di tipo. Speriamo che questo aiuti a spiegare come si desaga in scala grezza. Essenzialmente, la funzione ha un sacco di composizione funzionale.

2

Prima di tutto una guida per l'utente alla mia risposta: Userò corsivo per indicare una funzione che viene utilizzata senza essere esplicitamente denominata (vedere anonymous functions).

IsAuthenticated è un metodo che accetta come parametro un argomento f.

f è una funzione che prende Y come parametro e produce un'istanza di risultati

Y è una funzione che prende Z come parametro e produce un'istanza Request [AnyContent]

Z è una funzione che non accetta parametri e restituisce una stringa

IsAuthenticated chiama Security.Authentic attivato, passando nome utente e onUnauthorized (una funzione da chiamare quando l'utente non è autorizzato a eseguire l'azione richiesta).

Non sono del tutto sicuro di quello che sta succedendo qui passato myself- io non sono abbastanza che il bene con Scala ancora- ma la mia ipotesi è che Security.Authenticated è una classe caso, e la seguente è equivalente a sottoclassi e aggiungendo un costruttore in Java:

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

Se che gran parte della mia ipotesi è corretta, allora Azione (che è un metodo su Security.Authenticated) viene chiamato, passando come argomento un a.

A è una funzione che accetta un oggetto di Richiesta (sto indovinando con questo nome di classe) e produce un Risultato. L'utilizzo di Result è implicito qui perché l'implementazione di A è una chiamata a f.

Così quando viene instanciata la sottoclasse di Security.Authenticated, viene chiamato Action, che autentica l'utente per qualche azione (specificata come String) e quindi se l'utente è autenticato, restituisce f (il parametro originale) che è presumibilmente chiamato da Action (dopo l'autenticazione di cui sopra). Questa chiamata a f restituisce un risultato, che è anche una funzione. Il risultato viene infine chiamato con la richiesta (che è stata passata a A) come parametro.

Problemi correlati