odbhut.shei.chhele
odbhut.shei.chhele

Reputation: 6224

Understanding syntax of a scala function

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

Answers (3)

yǝsʞǝla
yǝsʞǝla

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

Arne Claassen
Arne Claassen

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

dhg
dhg

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

Related Questions