2011-09-07 3 views
0

Начиная с этого ответа:Повторное выполнение TRY блок после обработки исключения

Scala continuation and exception handling

Я хотел бы знать, если есть способ, чтобы повторно выполнить ВСЮ TRY блок (или ctry блок в код примера) после обработки исключения.

Что я имею в виду, если операция resume() может переместить выполнение в первый оператор блока try вместо простого возобновления выполнения из инструкции, которая вызвала исключение.

Большое спасибо!

+3

Я думаю, что это называется «петля». –

+0

Хорошо, следующий вопрос. Предположим, что блок try вызывает исключение. В блоке catch я меняю код внутри блока try (используя байт-код или перекомпилированный исходный код). Есть способ повторного выполнения блока NEW try? –

+1

@Niko - Я не понимаю, что вы подразумеваете, изменяя код в блоке catch. Вы динамически перезагружаете определение класса в приложении, а программа находится внутри этого класса? Не очевидно, как вы это сделаете (или это то, что вы имеете в виду), поэтому более подробная информация будет очень полезна. –

ответ

0

Вот глупый пример, который я думаю, что будет направлять вас к ответу:

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) 

} 

Идея заключается в том, чтобы вызвать shift блок до вашего try/catch блока. В блоке catch, если вы хотите повторить все, просто верните объект Retry.

Возможно, было бы неплохо вытащить весь блок shift в простую функцию (например, retry), но я оставил его встроенным для ясности.

Этот код производит следующий вывод:

[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 
Смежные вопросы