@kenjiyoshida has a nice gist that shows how to define Scala code. Note that if you use Eval from this value without specifying a return value, it will crash at runtime when Scala defaults to Nothing .
scala> Eval("println(\"Hello\")") Hello java.lang.ClassCastException: scala.runtime.BoxedUnit cannot be cast to scala.runtime.Nothing$ ... 42 elided
vs
scala> Eval[Unit]("println(\"Hello\")") Hello
It does an excellent job of being in scope.
object Thing { val thing: Int = 5 } object Eval { def apply[A](string: String): A = { val toolbox = currentMirror.mkToolBox() val tree = toolbox.parse(string) toolbox.eval(tree).asInstanceOf[A] } def fromFile[A](file: File): A = apply(scala.io.Source.fromFile(file).mkString("")) def fromFileName[A](file: String): A = fromFile(new File(file)) } object Thing2 { val thing2 = Eval[Int]("Thing.thing") // 5 }
Twitter util in the util-eval package, but this seems to be deprecated now (and also causes a compiler error when compiling).
As for the second part of your question, the answer seems no. Even if you disable Predef by default and import yourself, the user can always get these functions with the full package name. You could use Scala scala.tools.reflect.ToolBox to first scala.tools.reflect.ToolBox your string and then compare with a scala.tools.reflect.ToolBox before moving on to Eval , but at this point everything can get pretty hairy, as you will manually write code for Scala AST disinfection (or at least reject a dangerous entrance). This is definitely not like an "idiomatic solution."
source share