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)
Related
I am trying to write a function which can add a context to those functions given in parameters.
The idea is here
object example {
def withOne(f : => T) = {
val a = 1 //some context
f
}
def foo() = withOne {
println(a)
}
}
I think the context could be passed in implicit.
The idea is to not have the content of f constraint by the surrounding function f should be able to use the context or not.
For now the only way i seen to do that is like that
object example {
def withOne(f : => Int => T) = {
val a = 1 //some context
f(a)
}
def foo() = withOne { a =>
println(a)
}
}
But this forces to declare a 'a' witch is not obvious for others devs :x
I'm afraid you cannot work around this, since you cannot inject an implicit into a function.
There's a proposal to add this feature in the typelevel/scala fork, but it seems hard to achieve as of today.
My suggestion here is to use proper naming, so that you won't surprise your users. For instance if you provide a method like:
def withConnection[A](f: Connection => A): A = {
try {
val conn = ???
f(conn)
} finally {
conn.close()
}
}
it won't surprise me to do:
withConnection { implicit c =>
// db stuff
}
I am looking to rewrite this scala function, but I am new to the language, I understand there is a alternative to using try\catch blocks. How would you guys rewrite this function?
def updateStationPost = Action { implicit request =>
StationForm.bindFromRequest.fold(
errors => { //needs to be revised!!
BadRequest(html.updateStation(errors,
Station(
request.body.asFormUrlEncoded.get("id")(0).toLong,
request.body.asFormUrlEncoded.get("operator")(0).toLong,
request.body.asFormUrlEncoded.get("name")(0),
try {
request.body.asFormUrlEncoded.get("number")(0).toInt
} catch {
case e:Exception => { 0 } //this exception happens when trying to convert the number when there is nothing in the flash scope to convert.
},
request.body.asFormUrlEncoded.get("timezone")(0)
),
Operators.retrieveJustOperators() //ugh... needs to be revised..
)
)
},
{ case(stationFormObj) =>
Stations.update(stationFormObj)
Redirect(routes.StationsController.index)
}
)
}
A general way of managing this is to use Try to wrap code that could throw an exception. Some of the ways of using this are illustrated below:
def unpredictable() = {
Try(Console.readLine("Int please: ").toInt) getOrElse 0
}
If the console read does not contain a parseable integer, then it throws an exception. This code just returns a 0 if there was an error, but you could put other statements there. As an alternative, you could use pattern matching to handle the situation.
def unpredictable() = {
Try(Console.readLine("Int please: ").toInt) match {
case Success(i) => i
case Failure(e) => println(e.getMessage())
}
}
You can also just return a Try and let the caller decide how to handle the failure.
How about:
import scala.util.control.Exception.handling
// Create a val like this as you reuse it over and over
val form: Option[Map[String, Seq[String]]] = request.body.asFormUrlEncoded
// Create some helper functions like this
val nfeHandler = handling(classOf[NumberFormatException]) by (_ => 0)
val intNFEHandler = (str: String) => nfeHandler apply str.toInt
val longNFEHandler = (str: String) => nfeHandler apply str.toLong
// You can use this instead of your try catch.. but this is just a sugar.. perhaps cleaner
intNFEHandler apply form.get("id")(0)
Here if the form was something like: Option(Map("id" -> Seq.empty[String]))
form.get("id")(0) would blow up with java.lang.IndexOutOfBoundsException.
I would suggest to have another helper:
// takes fieldNames and returns Option(fieldValue)
val fieldValueOpt = (fieldName: String) => form.flatMap(_.get(fieldName).flatMap(_.headOption))
Then create a validate method which performs pattern matching on all the fieldValue optionals, extract the values and create your Station object.
I'm unhappy with the rule about variable scope in a try block not being shared with associated catch and finally blocks. Specifically it leads to code like the following:
var v: VType = null
try {
v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
As opposed to:
try {
val v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
Can anyone please explain or justify why this rule from Java persists?
and / or is there hope that this could change?
Thanks!
UPDATE
Many thanks for all the responses to date.
The consensus seems to imply "just get on with it" and I'm starting to conclude that perhaps technically what I want is either unsound, not worth the effort or hard to achieve.
I like Rex Kerr's answer but how would the original code above be wrapped in a method call without introducing a local var in the method body?
My own efforts weren't too good, using a by-name parameter to delay construction until safely in the try block works but still doesn't give me access to the constructed (or not) object in the catch or finally blocks.
Just "try" this ;)
val v = try { new VType() } catch { case e: Exception => /* ... */ }
In Scala, try is an expression, so it has a value.
You might be thinking about the problem the wrong way. Why do you want so much stuff in your try/catch/finally block? In your code,
try { val v = new VType() }
the exception could be thrown before you get v back, so you can't safely reference v. But if you can't reference v, then what can you do on the finally side that won't break or throw its own exception or have some other ill-defined behavior? What if you create v but fail to create w, but disposal requires having w as well? (Or doesn't?) It ends up being a mess.
But if you're coming from Java, there are a few things that can help you write try/catch/finally blocks in a sensible way.
One thing you can do is catch certain classes of exceptions and turn them into options instead:
def s2a(s: String) = try { Some(s.toInt) } catch { case nfe: NumberFormatException => None}
Another thing you can do is to create your own resource manager
def enclosed[C <: { def close() }](c: C)(f: C => Unit) {
try { f(c) } finally { c.close() }
}
enclosed(new FileInputStream(myFile))(fis => {
fis.read...
}
Or you can create your own shut-down-and-escape-safely method within another method:
val r = valuableOpenResource()
def attempt[F](f: => F) = {
try { f } catch { case re: ReasonableException => r.close() throw re }
}
doSomethingSafe()
attempt( doSomethingDangerous() )
doSomethingElseSafe()
r.close()
Between these different ways of handling things, I've not had much need to create vars to hold variables that I want to clean up later or otherwise deal with in catch or finally blocks.
How would this code work?
try
{
int i = 0;
// Do stuff...
Foo x = new Foo();
// Do more stuff...
Bar y = new Bar();
}
catch
{
// Print the values of i, x, and y.
}
What are the values of i, x, and y? Did y even get declared before we landed in the catch block?
The exception concept is not a subroutine of the try block, it is an alternate code flow. That makes at try-catch control block more like an "if anything untoward happens" then insert these (catch) lines in the current position of the try block, as needed.
With that in mind, it isn't clear if Val v = Type(); is going to be defined or not because the exception could (theoretically) be thrown before Val v = Type(); is evaluated. Yes, Val v is the first line in the block, but there are JVM errors which could be thrown before it.
Finally is another code construct which adds and alternate, but required, code flow the end of leaving the try-catch construct. Again, we have no idea how much (if any) of the try block was evaluated before the finally block was called, so we cannot depend on the declared variables within that block.
The only alternative left (now that we cannot use try block variables, due to their uncertainty of existence) is to use variable outside of the entire try-catch-finally construct for communications between the individual code blocks.
Does it suck? Maybe a little. Do we have anything that's better? Probably not. Putting the variable declarations outside of the block makes it obvious that the variables will have been defined prior to whatever control structure you process through in a try-catch-finally scenario.
If your main concern is that v should be immutable, you might get close to what you want with:
case class VType(name: String) {
// ... maybe throw an exception ...
}
val v = LazyVal(() => new VType())
try {
// do stuff with v
println(v.name) // implicitly converts LazyVal[VType] to VType
// do other unsafe stuff
} catch {
case e => // handle VType constructor failure
// can reference v after verifying v.isInitialized
} finally {
// can reference v after verifying v.isInitialized
if (v.isInitialized) v.safelyReleaseResources
}
where LazyVal is defined as
/**
* Based on DelayedLazyVal in the standard library
*/
class LazyVal[T](f: () => T) {
#volatile private[this] var _inited = false
private[this] lazy val complete = {
val v = f()
_inited = true
v
}
/** Whether the computation is complete.
*
* #return true if the computation is complete.
*/
def isInitialized = _inited
/** The result of f().
*
* #return the result
*/
def apply(): T = complete
}
object LazyVal {
def apply[T](f: () => T) = new LazyVal(f)
implicit def lazyval2val[T](l: LazyVal[T]): T = l()
}
It would be nice if we could use lazy val v = new VType(), but AFAIK there is no mechanism to safely determine whether a lazy val has been initialized.
Here's another alternative:
object Guard {
type Closing = {def close:Unit}
var guarded: Stack[Set[Closing]] = Stack()
def unapply(c: Closing) = {
guarded.push(guarded.pop + c)
Some(c)
}
private def close {println("Closing"); guarded.head.foreach{c => c.close}}
private def down {println("Adding Set"); guarded.push(Set())}
private def up {println("Removing Set"); guarded.pop}
def carefully(f: => Unit) {
down
try {f}
finally {close; up}
}
}
You can use it like this:
import Guard.carefully
class File {def close {println("Closed File")}}
class BadFile {def close {println("Closed Bad File")}; throw new Exception("BadFile failed")}
carefully {
val Guard(f) = new File
val Guard(g) = new File
val Guard(h) = new BadFile
}
which results in
Adding Set
Closing
Closed File
Closed File
java.lang.Exception: BadFile failed
So the first two files are created, then when the third constructor fails, the first two are automatically closed. All files are values.
Your example does not concretize why you need the finally clause. If VType is e.g. a resource that needs do be closed, you could do it one of the following ways.
1) You want to reference v after using it throws an exception:
try {
val v = new VType // may throw
try {
v.someThing // may throw
}
catch {
case ex => println("Error on doing something with v :" + v + ex) // or whatever
}
finally {
v.close()
}
}
catch {
case ex => println("Error on getting or closing v: " + ex) // v might not be constructed
}
2) You don't care about v in the catch clause:
try {
val v = new VType // may throw
try {
v.someThing // may throw
}
finally {
v.close()
}
}
catch {
case ex => println("Error on either operation: " + ex)
}
In either case, you get rid of the var.
Let's say I want to make a little wrapper along the lines of:
def wrapper(f: (Any) => Any): Any = {
println("Executing now")
val res = f
println("Execution finished")
res
}
wrapper {
println("2")
}
Does this make sense? My wrapper method is obviously wrong, but I think the spirit of what I want to do is possible. Am I right in thinking so? If so, what's the solution? Thanks!
If you want your wrapper method to execute the wrapped method inside itself, you should change the parameter to be 'by name'. This uses the syntax => ResultType.
def wrapper(f: => Any): Any = {
println("Executing now")
val res = f
println("Execution finished")
res
}
You can now do this,
wrapper {
println("2")
}
and it will print
Executing now
2
Execution finished
If you want to be able to use the return type of the wrapped function, you can make your method generic:
def wrapper[T](f: => T): T = {
println("Executing now")
val res: T = f
println("Execution finished")
res
}
In your case you are already executing the function println and then pass the result to your wrapper while it is expecting a function with one arguments (Any) and that return Any.
Not sure if this answer to your question but you can use a generic type parameter and accept a function with no arguments that return that type:
def wrapper[T](f: () => T) = {
println("Executing now")
val res = f() // call the function
println("Execution finished")
res
}
wrapper {
()=>println("2") // create an anonymous function that will be called
}
I have a helper method:
def controlStructure[T <: SomeObject](exceptions: Class[_]*)(body: => T) = {
try {
val tempObject = body
tempObject.callSomeMethod
Some(tempObject)
} catch {
case e if (exceptions.contains(e.getClass)) => None
}
}
called with:
controlStructure[MySomeObject](classOf[Exception]) { getMySomeObjectSomehow }
the main point of which is to call the 'callSomeMethod' on the entity passed in (for example loaded from ORM), it incidentally wraps things up in exception handling too.
I would now like to add a new method which does the same thing but for a collection (java.util.List) of T.
I am unsure of the syntax, and structures to work with a collection of T in the method signature, and abstract type param definitions.
Thanks for your help.
With a scala list, you are wanting something like this (I think):
def controlStructure[T <: SomeObject](exceptions: Class[_]*)(body: => List[T]) = {
try {
val tempObject = body
tempObject.foreach { _.callSomeMethod() }
Some(tempObject)
}
catch {
case e if (exceptions.contains(e.getClass)) => None
}
}
I haven't worked with Java lists in scala, so I'm guessing you could do it with java.util.List like this:
def controlStructure[T <: SomeObject](exceptions: Class[_]*)(body: => java.util.List[T]) = {
import scala.collection.JavaConversions._
try {
val tempObject = body
tempObject foreach { _.callSomeMethod() }
Some(tempObject)
}
catch {
case e if (exceptions.contains(e.getClass)) => None
}
}
There's no pass by name vararg in Scala. You have to pass a function if you want this. See this ticket of an enhancement request to this effect.
Thanks for your help Mitch. It turns out the answer is in this case to specify the return type of the method, as java.util.List[T], as for once Scala is not using its magic type inference to sort everything out.