2012-11-30 14 views
12

Sono nuovo di scala e il gioco. Qualcuno può tradurre il seguente frammento di seguito in inglese normale? Per il suo contesto trovate qui: http://www.playframework.org/documentation/2.0.4/ScalaSecurityHo bisogno di una semplice traduzione inglese del seguente snippet di scala

/** 
* This method shows how you could wrap the withAuth method to also fetch your user 
* You will need to implement UserDAO.findOneByUsername 
*/ 
def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request => 
    UserDAO.findOneByUsername(username).map { user => 
    f(user)(request) 
    }.getOrElse(onUnauthorized(request)) 
} 
+5

Non so perché stai ottenendo voti per chiudere la domanda. Penso che la tua domanda sia perfettamente legittima. Mi ero già visto quel codice prima e mi chiedevo come funzionasse. – huynhjl

risposta

21

Parte 1: Prima di tutto affrontare la sintassi al curry:

withUser è un metodo che accetta una funzione curry f di tipo User => Request[AnyContent] => Result. Prende un oggetto User e restituisce un'altra funzione che accetta uno Request e restituisce un Result. Scomponendola, se f è che la funzione allora:

val g = f(user) // g is a function 
val result = g(request) // returns a result 
// same as: 
val result = f(user)(request) 

In pratica f è proprio come una funzione che prende due parametri, ma invece di chiamare f(a, b) si chiama f(a)(b).

withAuth è anche un metodo che accetta una funzione al curry. Ha quasi lo stesso tipo di withUser.

Parte 2: Ora come si fa a utilizzare gli stessi metodi:

Come spiegato here, il gioco fa si è definito la logica dell'applicazione dicendo è come trasformare gli oggetti in RequestResult oggetti.

withAuth è una funzione di supporto che si occupa dell'autenticazione per te e recupera comodamente il nome utente. Quindi lo si utilizza in questo modo:

def index = withAuth { username => implicit request => 
    Ok(html.index(username)) 
} 

Si restituisce una funzione che prende un Request e restituisce un Result, che è quello che gioca esigenze. Ma ciò che serve è una funzione al curry (che accetta un nome utente) e restituisce una funzione (che accetta una richiesta). Il parametro di richiesta è contrassegnato come implicito in modo che possa essere trasmesso implicitamente a qualsiasi chiamata di funzione/metodo che richiede un parametro di richiesta implicito. Ai fini di questa spiegazione, ignora semplicemente la parola chiave implicit.

Parte 3: Traduzione di withUser

Beh, la sua firma è simile a withAuth e l'obiettivo è per essere usato nello stesso modo, tranne il primo parametro sarà una User invece di un String. Quindi deve prendere un User => Request => Result. La caratteristica richiesta richiede un parametro di tipo che indica il tipo del suo contenuto. Qui è AnyContent. Quindi il tipo corretto per l'argomento di withUser è User => Request[AnyContent] => Result.Ciò significa che sarà in grado di utilizzare in questo modo:

withUser { user => implicit request => 
    // do something with user and request to return a result 
} 

Se si guarda alla definizione di withUser, tutto ciò che fa è chiamare withAuth:

def withUser(f: User => Request[AnyContent] => Result) = withAuth { 
    // ... 
} 

Quindi tornerà lo stesso tipo come withAuth significa che restituirà una funzione che trasforma un Request in un Result (vedere la Parte 2 sopra). Il che significa che saremo in grado di utilizzare in questo modo:

def index = withUser { user => implicit request => 
    Ok(html.index(user)) 
} 

Ciò che è passato come argomento di withAuth è una funzione curry. Ho introdotto l'intermedio val in modo da poter seguire i seguenti tipi:

username => // first param is the username as a String 
    implicit request => // second param is the request 
    // here we have to return a Result... 
    // we lookup the user - we may not have one: 
    val userOption: Option[User] = UserDAO.findOneByUsername(username) 
    // f is the code block that will be provided inside withUser { f } 
    // Part 1 explains the f(user)(request) syntax 
    // We call f to get a result, in the context of the Option monad 
    val resultOption: Option[Result] = userOption.map(user => f(user)(request)) 
    // if we have a result, return it; otherwise return an error. 
    resultOption.getOrElse(onUnauthorized(request)) 
+0

Grazie per la risposta molto dettagliata. Sei andato ben oltre! – critium

Problemi correlati