Ответ 1
Вы можете легко переопределить метод breakIf
в своем коде. Я не думаю, что есть намного более чистый способ сделать это.
Сначала вам нужно добавить библиотеку компилятора scala к build.sbt
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
с классом из вашего проекта (см. Мой ответ на еще один вопрос).
Вы можете использовать новый breakIf
следующим образом:
val x = 10
breakIf[X](assertion = true, NamedParam("x", "Int", x))
Где X
- это только некоторые из ваших классов.
Я не знаю, отвечает ли это на ваш вопрос, потому что трудно измерить, что легко и что сложно.
Кроме того, в качестве побочного примечания - если вы хотите использовать его для целей отладки, почему бы не использовать отладчик. Я думаю, что большинство отладчиков могут подключаться к программе, останавливаться в точке останова и оценивать выражения в этом контексте.
Изменить
Похоже, что он не работает с текущей версией 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))