Scala:生成一个有条件地运行另一个块的块

时间:2011-07-10 15:12:01

标签: scala codeblocks

Circumflex framework中,您可以将网址映射到这样的网址:

get("/foo") = {
    "hello, world!"
}

,当浏览到/foo时,将按预期显示给定的字符串。现在,要编写完整的Web应用程序,您几乎总是需要某种形式的身份验证和授权。我正在尝试为上面的构造编写某种包装器,所以我可以这样写:

get("/foo") = requireLogin {
    "hello, world!"
}

然后requireLogin方法将检查用户是否已登录,如果是,则执行给定的块。但是,如果没有,则应该重定向到登录页面。

现在我以某种方式无法正确使用语法(我仍然是Scala新手)。你会如何以通用的方式做到这一点?

3 个答案:

答案 0 :(得分:4)

尝试这样的事情:

def executeMaybe[A](work: => A): Option[A] =
  if (util.Random.nextBoolean)
    Some(work)
  else
    None

这将以概率0.5执行传递的代码,返回Some(<result delivered by work>),或返回None是其他情况。您可以这样称呼它:

val v = executeMaybe(42)

或使用块表示法:

val v = executeMaybe {
  // do some work
  // provide return value
}

诀窍是使用 by-name参数,由=>符号发出信号。阅读更多内容在这里:http://daily-scala.blogspot.com/2009/12/by-name-parameter-to-function.html

答案 1 :(得分:3)

我问的方式,Jean-Philippe的回答是正确的。 但这里有一些特定于Circumflex的信息:

在Circumflex RequestRouter中,以下内容可用于实现所需方法:

def requireLogin (f: => RouteResponse ): RouteResponse = {
    if(loggedIn) {
        return f
    }
    else {
        return sendRedirect("/login")
    }
}

这背后的原因是让Jean-Philippe回答的提示变得清晰,并且一旦我记得以下调用不是将块分配给某些内部数据,而是映射到另一个方法调用。 / p>

所以,电话

get("/") = {...}
实际上

映射到:

get.update("/", {...})

该块作为By-Name参数传入,因此requireLogin的返回值必须相同 - 对于Circumflex,它是RouteResponse,而不是函数。

答案 2 :(得分:-1)

您还可以在web.xml中使用<login-config><security-constraint>内容的j2ee容器身份验证