ssyys
ssyys

Reputation: 23

Scala implement inline trait method

I've started learning scala and the play framework. I downloaded the sample project from the play framework site. I have a newbie question because I cannot understand the following syntax:

def count = Action { Ok(counter.nextCount().toString) }

What exactly does it do? Action is implemented function in BaseController, where action builder is assigned. What is the content the beetwen braces for? Wat do the braces mean in this context?

Upvotes: 1

Views: 680

Answers (2)

Ra Ka
Ra Ka

Reputation: 3055

In playframework, requests are handled by Actions. When you invoke Action { ... }, you are actually invoking play.api.mvc.Action helper object to create Action values.

object Action extends ActionBuilder[Request] { ... } 

If you look closely to Action object, it extends to play.api.mvc.ActionBuilder trait. This trait contains various overloaded apply methods that creates Action values. Therefore, when you are invoking Action{ ... } you are actually invoking Action.apply({...}) and this apply method is inherited from ActionBuilder trait. If you look into ActionBuilder trait, you will see various higher ordered apply functions.

Now in your case, def count = Action { Ok(counter.nextCount().toString) }

You are actually invoking apply method with default content and no request parameter.

final def apply(block: => Result): Action[AnyContent] = apply(_ => block)

That means, you are providing block { Ok(counter.nextCount().toString) } which return Ok Result.

What is the content the beetwen braces for? Wat do the braces mean in this context?

When you do Action { Ok(counter.nextCount().toString) }, you are actually invoking:

Action.apply(Ok(counter.nextCount().toString))

In scala, apply method is a factory method and therefore you don't have to essentially call apply method, therefore you can also do Action(Ok(counter.nextCount().toString)). Additionally, if your function takes only single parameter, you can replace () brackets with curly braces {}. i.e. you can do Action{Ok(counter.nextCount().toString)}.

I would suggest to look into function literals, higher ordered functions, by-name parameter, method currying etc. So, that you will have more insight in these.

Upvotes: 3

Dennis Hunziker
Dennis Hunziker

Reputation: 1293

The source code will give you the details:

/**
   * Constructs an `Action` with default content, and no request parameter.
   *
   * For example:
   * {{{
   * val hello = Action {
   *   Ok("Hello!")
   * }
   * }}}
   *
   * @param block the action code
   * @return an action
   */
  final def apply(block: => Result): Action[AnyContent] =
    apply(BodyParsers.utils.ignore(AnyContentAsEmpty: AnyContent))(_ => block)

It's equivalent to def count = Action.apply(Ok(counter.nextCount().toString))

Upvotes: 0

Related Questions