Reputation: 6224
I am trying to learn scala. I know how to write a function. This is how I write a function.
def test_function: Unit = {
println("This is just a test")
}
But then I started learning playframework. This is how they write a function in controller in play.
def test_function: Unit = Action{
println("This is just a test")
}
My question is what is this Action doing before the curly braces? What is it called? How can I write my own? I hope I have made my question clear. Thanks in advance.
Upvotes: 1
Views: 90
Reputation: 16412
Action
is a trait (play.api.mvc.Action
). Essentially it represents this type: play.api.mvc.Request => play.api.mvc.Result
(doc1, doc2).
In your case you are using Action {...}
which is equivalent to Action(...)
and converted by compiler to Action.apply(...)
call. If you check source code you'll see the apply
method signatures defined not only on the Action
trait and it's companion object, but also in here:
/**
* Provides helpers for creating `Action` values.
*/
trait ActionBuilder[+R[_]] extends ActionFunction[Request, R]
In your case you are not taking any request and not producing any response, so essentially your Action
is a function call of a form apply(block: => Result)
where Result
is thrown away since you define return type of your function as Unit
.
Action
supports many ways you can handle its body (including Futures) so pick the right apply
method to cover your needs.
You can extend Action
if you need to since it's not a final implementation. Here is an example:
case class Logging[A](action: Action[A]) extends Action[A]
Upvotes: 2
Reputation: 14394
Action
is basically a function alias of the shape play.api.mvc.Request => play.api.mvc.Result
. When you see Action { }
, you are actually seeing apply
function of the companion object of that type and are passing a body that should provide that Request => Result
function.
The companion object has roughly the shape of:
object Action {
def apply(f: Request => Response): Action = ...
}
so that when you call Action { ... }
, the { ... }
is that function that will be executed when the action is invoked.
In your example, println("This is just a test")
serves as the provider of the Result
.
Upvotes: 1
Reputation: 52681
You can get this kind of behavior by defining an apply
method on an object
called Action
:
object Action {
def apply(block: => Unit): Unit = {
println("before")
block // do the action in the block
println("after")
}
}
Then both of these:
Action { println("hi") }
Action(println("hi"))
Produce this:
before
hi
after
The thing in braces after Action
is just the argument to the apply
method. Scala allows either parentheses or braces, but using braces allows you to put multiple statements in:
Action {
println("a")
println("b")
}
yields:
before
a
b
after
Upvotes: 2