gpt4 book ai didi

scala - 在程序执行过程中进入 REPL 控制台的干净解决方案

转载 作者:行者123 更新时间:2023-12-04 02:21:06 25 4
gpt4 key购买 nike

是否有任何适用于 Scala 2.10 的 REPL 控制台的可行解决方案?

这主要用于调试目的 - 我想在执行过程中暂停,并有一个 REPL 控制台,我可以在其中检查值并在当前执行状态下使用程序中的复杂表达式测试程序的逻辑。用过 Ruby 编程的人可能知道类似的功能:binding.pry .

AFAIK、Scala 2.9 及更低版本曾经有 breakIf但它已从更高版本中删除。使用 ILoop似乎是新方法,但由于 sbt 而引入了问题不将 scala-library 添加到类路径中。

this等几种解决方案和 this似乎提供了一个很好的解决方法,但我的观点是必须有一个解决方案,我不必花费数小时甚至数天来使 REPL 正常工作。

简而言之,涉及更多样板步骤 - 这与 binding.pry 形成对比。这只是一行代码,没有额外的样板。

我不知道在将程序作为 sbt 任务执行时是否引入了问题,而不是直接运行程序可执行文件,但出于开发目的,我目前正在使用 sbt 任务运行和测试我的程序。

最佳答案

您可以轻松地重新实现 breakIf代码中的方法。我认为没有更清洁的方法可以做到这一点。

首先你必须在你的 build.sbt 中添加一个 scala 编译器库。

libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value

完成后,您可以实现 breakIf
import scala.reflect.ClassTag
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ILoop, NamedParam}

def breakIf[T](assertion: => Boolean, args: NamedParam*)(implicit tag: ClassTag[T]) = {
val repl = new ILoop()

repl.settings = new Settings()
repl.settings.embeddedDefaults[T]
repl.settings.Yreplsync.value = true
repl.in = repl.chooseReader(repl.settings)

repl.createInterpreter()

args.foreach(p => repl.bind(p.name, p.tpe, p.value))

repl.loop()
repl.closeInterpreter()
}

我认为这很简单,唯一棘手的部分是您必须正确设置类路径。您需要调用 embeddedDefaults使用您项目中的类(class)(请参阅我对 another question 的回答)。

您可以使用新的 breakIf如下:
val x = 10
breakIf[X](assertion = true, NamedParam("x", "Int", x))

在哪里 X只是你的一些类(class)。

我不知道这是否回答了你的问题,因为很难衡量什么是容易的,什么是困难的。

另外,作为旁注 - 如果您想将其用于调试目的,为什么不使用调试器。我猜大多数调试器都可以连接到程序,在断点处停止并在该上下文中评估表达式。

编辑

似乎它不适用于当前版本的 Scala 2.10,工作代码似乎是:
import scala.reflect.ClassTag
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ILoop, NamedParam}

def breakIf[T](assertion: => Boolean, args: NamedParam*)(implicit tag: ClassTag[T]) = {

val repl = new ILoop() {
override protected def postInitialization(): Unit = {
addThunk(args.foreach(p => intp.bind(p)))
super.postInitialization()
}
}

val settings = new Settings()

settings.Yreplsync.value = true
settings.usejavacp.value = true
settings.embeddedDefaults[T]

args.foreach(repl.intp.rebind)

repl.process(settings)

}

用法就像
  val x = 10
breakIf[X](assertion = true, NamedParam("x", x))

关于scala - 在程序执行过程中进入 REPL 控制台的干净解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24674288/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com