0

When you see code that follows this pattern:

def index = Action { request =>
  // ..
}

Action trait: https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L65

When looking at this code, how would you know that the request object is available to use within the code block? (is there a intellij shortcut for this?)

Can someone please create a miniature example of where you can mimic this pattern so I can understand how this works, and if you can explain in technical terms what is going on?

0

2 Answers 2

3

The Action trait is not of interest here. Instead, because the body of the index method must be a value, not a type, you are looking at the Action object. You can learn more about objects here. Let's first simplify the syntax by removing syntactic sugar, i.e. making the program behave the same but with simpler constructs. If you try to call an object as if it were a method, what really happens is that .apply is inserted for you by the compiler:

def index = Action.apply((request) => {
  // ..
})

This may be more familiar; the apply method is being called on the Action object, passing a lambda function that takes a request. And obviously, an argument to a lambda is always available within that lambda. That's the point of them.

The lambda in this case is also known as a callback. A simple example that clarifies these features follows:

object WithAnswer {
  def apply(f: Int => Unit): Unit =
    f(42)
}

def printAnswer() = WithAnswer { answer =>
  println(answer)
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. Yes you are passing a request to the lambda and therefore you can use it inside of the lamba I go tthat. But how do you know which parameters are available? Can IntelliJ tell me this easily or?
in your example, you have the parameter 'answer', what is that?
It is the integer that WithAnswer.apply passes to the lambda.
I just find it wierd, because the integer is hard coded (42) instead of being passed in as a parameter in the WithAnswer block.
How could you pass the integer from within your block?
|
1

This is called as Loan pattern

withWriter creates a writer for the user and then ensures the resource (writer) is properly closely after using.

All that user has to do is just use the writer and write something to the file

def withWriter(file: File)(f: Writer => Unit): Unit = {
  val writer = new PrintWriter(file)
  try {
    f(writer)
  } finally {
    writer close
  }
}

Usage:

 withWriter(new File("some_fix.txt") { writer =>
   writer println("write something")
 }

1 Comment

are you sure it is a loan pattern since that would be definitely relevant to resource management? i haven't read play source, but this page only mentions it accepts a function

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.