2012-03-09 12 views
7

Mam metodę, z dużo parametrów ukrytych:niejawny w ciągu wzorca meczu

def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...} 

Teraz rozważmy taką klasę:

object Users extends Controller { 
    implicit a: A = ... 
    implicit b: B = ... 
    ... 

    def index(id:String) = Action { 
    User.findById(id) match { 
     case Some(user) => { 
      implicit val _user = user 
      hello("implicit") 
     } 
     case _ => BadRequest 
    } 
    } 
} 

widać to wiersz w powyższym próbki:

implicit val _user = user 

To istnieje tylko, aby obiekt user jako domniemany obiektu. W przeciwnym razie, muszę zadzwonić hello jak:

hello("implicit")(a,b,c,... user) 

myślę, czy istnieje jakiś sposób, aby poprawić kod, na przykład nie musimy definiować tej zmiennej _user, ale powodujemy, że user jest niejawne.

Odpowiedz

5

Tak, istnieje sposób, aby wyeliminować _user zmienną robiąc user niejawny:

def index(id:String) = Action { 
    User.findById(id) map (implicit user => hello("implicit")) getOrElse BadRequest 
} 

UPDATE: Adresowanie twoje pytanie na temat wielu przypadków w komentarzach poniżej.

Wszystko zależy od tego, jaki typ wartości zostanie zwrócony przez User.findById. Jeśli to Option[User] ale chcesz dopasować na konkretnych użytkowników (zakładając User jest klasą przypadek), to oryginalne rozwiązanie nadal obowiązuje:

def index(id:String) = Action { 
    User.findById(id) map { implicit user => 
    user match { 
     case User("bob") => hello("Bob") 
     case User("alice") => hello("Alice") 
     case User("john") => hello("John") 
     case _ => hello("Other user") 
    } 
    } getOrElse BadRequest 

Albo można dopasować na cokolwiek innego, jeśli chcesz, tak długo, jak User.findById jest String => Option[User]

Jeśli, z drugiej strony, User.findById jest String => User następnie można po prostu zdefiniować obiekt pomocnika takiego:

object withUser { 
    def apply[A](user: User)(block: User => A) = block(user) 
} 

i używać go jako fo llows (znowu zakładając User jest klasa przypadek):

def index(id: String) = Action { 
    withUser(User findById id) { implicit user => 
    user match { 
     case User("bob") => hello("Bob") 
     case User("alice") => hello("Alice") 
     case User("john") => hello("John") 
     case _ => BadRequest 
    } 
    } 
} 

lub dopasowywania na jakiejś innej wartości, powiedzmy Int:

def index(id: String, level: Int) = Action { 
    withUser(User findById id) { implicit user => 
    level match { 
     case 1 => hello("Number One") 
     case 2 => hello("Number Two") 
     case 3 => hello("Number Three") 
     case _ => BadRequest 
    } 
    } 
} 

Mam nadzieję, że ten obejmuje wszystkie scenariusze mogą mieć.

+0

+1, to dobre rozwiązanie, jeśli wzór pasuje do opcji. Ale co, jeśli jest wiele "przypadków"? – Freewind

+0

@Freewind. Zaktualizowałem swoją odpowiedź, aby objąć wiele "przypadków". – romusz

2

Nie znam sztuczki, takie jak sprawy Some(implicit user) ale co

def hello(message: String, user: User)(implicit a: A, ... z: Z) = ... 
def hello(message: String)(implicit a: A, ... z: Z, user: User) = hello(message, user) 

case Some(user) => hello("implicit", user) 
+0

Dziękuję. Myślę, że 'hello (message) (implicit ...)' powinno być istniejące i nie może być zmienione, w przeciwnym razie nie będziemy musieli go zdefiniować, wystarczy zdefiniować 'hello (message, user) (implicit .. .) 'on wystarczy. – Freewind