Wrapping Methods with a Thunk in Scala - scala

I have several methods in my class, each taking in different parameters and returning different parameters. For each of those methods, I want to wrap them in a common piece of code that would do some time logging. For example., when the method starts, it logs the start time and when it ends, it logs the end time and so on.
I have this method implemented:
def withTimerMetrics(fn: => _) = {
Try(AppMetrics.timer.time()).map(context => {
fn
context.close()
})
}
Where the fn is one of the method that is implemented in my class.
Obviously, I get an unbound wildcard error. Is there a way I could do this? I do not want to use Scala macros for this. Any other ideas?

You have wrong method signature. Try this:
def withTimerMetrics[T](fn: => T) = {
Try(AppMetrics.timer.time()).map(context => {
fn
context.close()
})
}
Not sure, why you wrap time() in Try (is it codahale metrics?), because now your function cannot be timed without changing output. I would say it should be somehow so:
def withTimerMetrics[T](fn: => T): T = {
val c = AppMetrics.timer.time()
try {
fn
} finally {
context.close()
}
}
So you can measure execution time without changing in your application logic.

Related

Global try/catch implementation in scala

I am trying to look for the Global try/catch method for all my methods to handle the exception and return the same.
private def myMethod() {
try {
methodThatThrowsIOException()
} catch (IOException e) {
//What to do?
}
}
So, rather then separately calling try catch in each method , can I design a common method which will handle try/catch exception for my all other methods in scala.
here I need to make myMethod() generic and pass any methodThatThrowsIOException() .
When passing blocks to a function, especially when that function is then used all over the place with different inputs, I tend to separate it into its own parameter list:
private def myMethod[T](block: => T): Try[T] = {
Try(block())
}
This is often easier to read, e.g.:
val result = myMethod {
// your code
}
You then match on result for Failure in order to access the exception as you've asked for. If there's never a return type on methodThatThrowsIOException then you can further simplify and maybe use an Option instead of Try.
you can implement an higher order function that receives everything you'd need (sort of a template pattern). Something like this
private def myMethod[T](block: => T, errorHandling: Throwable => Any) {
Try(block()) match {
case Success(s) => s
case Failure(e) => errorHandling(e)
}
}

scala returning a Future[Option[user]]

So, I am totally new to Scala, coming from a Java background and have been given a huge scala code base to learn. And, I am very lost and would appreciate any help.
I have the below function that I want to re-arrange. Currently, the function calls two functions in a row and then returns the result. The first function returns a boolean and the second function returns a User. However, what actually should happen is that the second function should only be called if the first function returns true. So, I need to rearrange it to check the return value of the first function before continuing. Every time I rewrite it to do that, I either get a compile error or exception. It is supposed to return a Future[Option[User]] and the first function doesn't return a User. I just want to return None if FunctionA fails, but because it expects Future[Option[X]]], it is unhappy. So, below is the function:
private def profileForCredentials(userId: String, password: String)(implicit ec: ExecutionContext): Future[Option[User]] =
{
val credentials: Throwable \/ Boolean = {
try {
FunctionA(userId, password).right[Throwable]
}
catch {
case npe: NullPointerException =>
npe.left[Boolean]
}
}
//This function doesn't need to be called unless credentials=true
FunctionB(id, userId).map {
case maybeUser#Some(user) =>
credentials match {
case \/-(x) if x =>
user.some
case _ =>
None
}
case None =>
None
}
}
You guys just got carried away with the scalaz.
I am going to bookmark this page to show people at work as an illustration why we should not be using all this fancy stuff.
Just do this:
Try {
FunctionA(userId, password)
}
.toOption
.collect { case(true) =>
FunctionB(id, userId)
}
.getOrElse(Future.value(None))

Scala Lifting to a thunk

I have a function that wraps the result of another function in a Promise. I wanted to promote this into a lift function so that I could sort of re-use it elsewhere. Here are the original definitions:
val abc = Promise[MyType]()
try {
val suck = abc.success(someOtherFunction(intParam1, intParam2))
} catch {
case ex: Exception => p.failure(ex)
}
So what I eventually did was the following:
def myLiftFunc[X](x: X) (op: => X): Promise[X] = {
val p = Promise[X]()
try {
p.success(op)
} catch {
case NonFatal(ex) =>
p.failure(ex)
}
p
}
How can I re-use this? I mean, the second argument that I pass in should be a thunk so that I could just pass in any function body irrespective of the parameters that function body would require!
When I call the lifted function as:
myLiftFunc(someOtherFunction(intParam1, intParam2))
This is of type Int => Promise[Int], where the someOtherFunction returns an Int. I just want Promise[Int] when I call myLiftFunc!
You might be interested in the Promise.fromTry method. That method uses the Try idiom from scala.util, which is a useful structure that allows you to treat a try...catch statement more like a traditional constructs:
Promise.fromTry { Try { someOtherFunction(intParam1, intParam2) } }
If you wanted to right your own helper (so that the Try part is unnecessary, you could try something like:
def myLiftFunc[X](op: => X): Promise[X] = Promise.fromTry(Try(op))
This would allow you to do:
myLiftFunc { /*arbitrary logic*/ }
myLiftFunc(1 + 4).future.value.get //Success(5)
myLiftFunc(1/0).future.value.get //Failure(java.lang.ArithmeticException: / by zero)

scala - make variable available inside block

Having a function that is used like this:
xpto.withClient {
client => client.abcd
}
I would like to wrap it in an object:
object X {
def foo[T](block: => T): T = {
xpto.withClient {
client => {
block
}
}
}
}
to make it possible to be used like this:
object Y {
def bar : Unit {
X.foo {
client.abcd
}
}
}
This doesn't seems to be making the client value available inside the block though. Is this possible? Making the client variable available inside the block definition? I've looked around with implicits in Scala but so far no good.
That won't work, because block is just something that produces a value of T. It doesn't have the same scope. Supposing that client has type Client, then block should be a function Client => T. foo would then pass the client to block.
def foo[T](block: Client => T): T = {
xpto.withClient { client =>
block(client)
}
}
Or more concisely:
def foo[T](block: Client => T): T = xpto.withClient(block(_))
However, that will change your usage to this:
object Y {
def bar : Unit {
X.foo { client =>
client.abcd
}
}
}
Of course, this does nothing but thinly wrap xpto.withClient. The thing is, you need to have a way to pass client down the chain. Doing this implicitly won't really help either, because you still need a client identifier within that anonymous block of code.

Play Framework/Scala: "return" statement in Action?

I know that this is not the Scala way of writing things. I think, in Scala you would use map. But I would like to write it this way, because it is more Java/c++ like.
However writing the following code the Scala compiler complains "method addGroup has return statement; needs result type".
Omitting the return and using an else branch works. But for formating reasons I'd like to use a return, because I don't want to indent the rest of the code which would happen if you use "else {}".
Where to add the result type. And is "Future[Result]" the correct type?
def addGroup = Action { implicit request =>
val optionUser = GetUserFromSession(request)
if (optionUser == None) {
return Redirect(routes.ApplicationUser.show(0))
}
Redirect(routes.ApplicationUser.show(optionUser.get.id))
}
You can't. The body of Action.apply is an anonymous function that you're trying to prematurely return from. The problem is, the return keyword in Scala returns from the inner-most named method, which this most certainly is not. So you'll be trying to return a Result where the method requires a Action[A].
The only way this can work is if you split the functions:
def addGroup = Action { implicit request =>
result(request)
}
// Could have a better name, but whatever, you shouldn't do this.
def result(request: Request): Result = {
val optionUser = GetUserFromSession(request)
if (optionUser == None) {
return Redirect(routes.ApplicationUser.show(0))
}
Redirect(routes.ApplicationUser.show(optionUser.get.id))
}
Using return makes code weird and difficult to read, so please don't.
If saving a single indentation is really a concern, what about this?
def addGroup = Action { implicit request =>
val optionUser = GetUserFromSession(request)
if (optionUser == None) Redirect(routes.ApplicationUser.show(0))
else Redirect(routes.ApplicationUser.show(optionUser.get.id))
}
Personally, I would re-write this using map and getOrElse:
def addGroup = Action { implicit request =>
GetUserFromSession(request) map { user =>
Redirect(routes.ApplicationUser.show(user.id))
} getOrElse {
Redirect(routes.ApplicationUser.show(0))
}
}
It removes the need to use .get and also prioritizes the positive branch.