Re-execute TRY block after the exception is handled
Starting from this answer:
Scala continuation and exception handling
I would like to know if there is a way to re-execute the ENTIRE try block (or ctry block in the example code) after the exception is handled.
What I mean is if the resume() operation could move the execution to the开发者_C百科 first statement of the try block instead of simply resuming the execution from the statement that raised the exception.
Thanks a lot!
Here's a silly example that I think will steer you toward an answer:
object Retry
object SO_7331489 extends App {
import scala.util.continuations._
var dividend: String = "ten"
var divisor: Int = 0
val quotient = reset {
shift { k: (Unit => Any) =>
def retry: Any =
k() match {
case Retry => retry
case x => x
}
retry
}
try {
dividend.toInt / divisor
} catch {
case e: java.lang.NumberFormatException =>
println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
dividend = "10"
println("retrying with dividend = \"10\"")
Retry
case e: java.lang.ArithmeticException =>
println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
divisor = 2
println("retrying with divisor = 2")
Retry
case t: Throwable =>
println("caught " + t.getClass.getName + "(" + t.getMessage + ")")
// Nothing left to retry, so don't return Retry
}
}
println("quotient: " + quotient)
}
The idea is to trigger the shift
block before your try/catch
block. Within the catch
block, if you want to retry the whole thing, simply return the Retry
object.
It might be nice to pull the entire shift
block out into a simple function (e.g. retry
), but I left it inline for clarity.
This code produces the following output:
[info] Running SO_7331489
caught java.lang.NumberFormatException(For input string: "ten")
retrying with dividend = "10"
caught java.lang.ArithmeticException(/ by zero)
retrying with divisor = 2
quotient: 5
精彩评论