For lift development, I sometimes need to use match
–case
statements like the following. (Rewritten to plain scala for easier understanding.) One note to them: These are actually different partial functions, defined in different parts of the code, so it’s important that a case statement fails in or before the guard in order to have the other partial functions evaluated (if matching fails, that is).
// The incoming request
case class Req(path: List[String], requestType: Int)
// Does some heavy database action (not shown here)
def findInDb(req: Req):Option[Int] =
if(req.path.length > 3) Some(2) else None
Req("a"::"b"::Nil, 3) match {
case r@Req(`path` :: _ :: Nil, 3) if findInDb(r).isDefined =>
doSomethingWith(findInDb(r))
case r@Req(`path` :: _ :: Nil, _) => doDefault
case _ => doNothing
}
Now, in order to know that the case
statement succeeds, I must query the database with findInDb
and check whether the result is valid. Afterwards, I must call it again to use the value.
Doing something like
case r@Req(path, 3) if {val res = findInDb(r); res.isDefined} =>
does not work because the scope of res
is then limited to inside the braces.
I can of course define a var res = _
outside and assign to it, but I don’t feel well doing this.
Is it by any means possible to declare a variable inside the guard? If it is possible to do case r@Req(…)
why not case r@Req() if res@(r.isDefined)
?