加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何以编程方式检查scala解释器内发生的错误

发布时间:2020-12-16 09:05:21 所属栏目:安全 来源:网络整理
导读:我正在使用 scala.tools.nsc.Interpreter执行scala代码片段 当代码片段正确时,一切都很好,但是当它有错误时,我的代码无法找到并愉快地继续下去.我想获得一个异常或方法来调用以获取解释器在上次评估期间发生的任何错误. 我的代码: import scala.tools.nsc.I
我正在使用 scala.tools.nsc.Interpreter执行scala代码片段
当代码片段正确时,一切都很好,但是当它有错误时,我的代码无法找到并愉快地继续下去.我想获得一个异常或方法来调用以获取解释器在上次评估期间发生的任何错误.

我的代码:

import scala.tools.nsc.Interpreter
import scala.tools.nsc.Settings
object RuntimeEval {
  def main(args: Array[String]): Unit = {
    var msg = "fail"
    val eval = new RuntimeEval
    msg = eval.eval(msg,""success"")
    println(msg)
    var anInt = 0
    while(true){
    println("Enter an integer")
      val userInput = Console.readLine
      anInt = eval.eval(anInt,userInput)
      println("-->"+anInt)
      println
    }
  }
}
class ResContainer(var value: Any)
class RuntimeEval {
  val settings = new Settings
  settings.classpath.value = System.getProperty("java.class.path")
  val interp = new Interpreter(settings)

  def eval[A <: Any](obj: A,expression: String): A={
    val res = new ResContainer(obj)
    interp.beQuietDuring {
      interp.bind("res",res.getClass.getCanonicalName,res)
      interp.interpret("res.value = "+expression)
    }
    val info = obj match{
      case x: AnyRef => "expected type: n"+x.getClass.getCanonicalName+"n"
      case _ => "expected type is not an AnyRefn"
    }
    res.value match{
      case x: A => x
      case x: AnyRef => error("unexpected result type,"+info+"result type:n"+x.getClass.getCanonicalName)
      case _ => error("unexpected result type,"+info+"result type is not an AnyRef")
    }
  }
}

问题的一个例子:

success
Enter an integer
9/12
-->0

Enter an integer
9/0
java.lang.ArithmeticException: / by zero
    at .<init>(<console>:6)
    at .<clinit>(<console>)
    at RequestResult$.<init>(<console>:5)
    at RequestResult$.<clinit>(<console>)
    at RequestResult$scala_repl_result(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
    at scala.util.control.Exception$Catch.apply(Exception.scala:79)
    at scala...-->0

Enter an integer
9/4
-->2

Enter an integer

ArithmeticException发生在解释器内部,然后似乎没有返回任何内容,所以我的代码得到了与前一个操作相同的结果,0.
怎么抓住这个?

解决方法

Interpreter的解释方法返回一个结果值,指示代码是否可以成功解释.从而:

interp.beQuietDuring {
  interp.bind("res",res)
  interp.interpret("res.value = "+expression)
} match {
   case Results.Error => error( ... )
   case Results.Incomplete => error( ... )
   case Results.Success => res.value
}

还有两件事:你不需要为每个eval绑定“res”,一旦你初始化解释器就应该这样做了.另外,请注意有一个方法mostRecentVar,因此您可以完全取消结果绑定.以下是Scala 2.9的示例(与2.8相同,但您使用的不是Interpreter):

import tools.nsc.interpreter.{IMain,Results}
import sys.error
val interp = new IMain()
def eval( expression: String ) : AnyRef =
   interp.interpret( expression ) match {
      case Results.Error => error( "Failed" )
      case Results.Incomplete => error( "Incomplete" )
      case Results.Success => interp.valueOfTerm( interp.mostRecentVar )
        .getOrElse( error( "No result" ))
   }

测试:

scala> val x = eval( "1 + 2" )
res0: Int = 3
x: AnyRef = 3

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读