开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜