Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.currentMirror
scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox
scala> def eval(code: String) = {
| val toolbox = currentMirror.mkToolBox()
| toolbox.eval(toolbox.parse(code))
| }
eval: (code: String)Any
scala> eval("1 + 2")
res0: Any = 3
scala> eval("<a>b</a>")
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
not found: value $scope
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:316)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.wrapInPackageAndCompile(ToolBoxFactory.scala:198)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:252)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2.apply(ToolBoxFactory.scala:429)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2.apply(ToolBoxFactory.scala:422)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.liftedTree2$1(ToolBoxFactory.scala:355)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:355)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:422)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scala:444)
at .eval(<console>:11)
not fould: value $scope
是什么意思?
答案 0 :(得分:3)
这可能与以下事实有关:XML支持是从scala 2.11开始在一个单独的库中提取的,因为尝试scala 2.10中的代码片段就像魅力一样。
似乎无法找到$scope: scala.xml.TopScope
。
在scala 2.10。*中,它在Predef
中定义。
从scala 2.11.0开始,编译器不能指望此值始终可用,因为您必须显式包含xml库。 考虑到这一点,我们可能想知道工具箱是否可以访问xml库。我们知道它可以在REPL中访问(它是自动导入的),很容易检查:
scala> xml.Text("foo")
res18: scala.xml.Text = foo
scala> <a>b<a>
res19: scala.xml.Elem = <a>b</a>
但是,$scope
本身是否可以访问?
scala> $scope
<console>:13: error: not found: value $scope
$scope
^
糟糕。为什么它不可访问,老实说我不知道,但我认为即使在xml库中也没有任何$scope
值,并且该值由编译器神奇地合成。这种魔法似乎在工具箱中失败了。
作为参考,如果您在scala 2.10.0中尝试相同,它可以正常工作:
scala> $scope
res2: xml.TopScope.type =
无论如何,这显然是问题的根源。如果REPL本身找不到$scope
,那么工具箱(从REPL中的运行时Universe创建)也找不到它也就不足为奇了(甚至在REPL之外也可能存在同样的问题)。
这可能可能被归类为错误(至少应该被报告),但至少有一个丑陋但简单的解决方法:
scala> eval("val $scope = scala.xml.TopScope; <a>b</a>")
res22: Any = <a>b</a>
当然,您实际上想要修改eval
本身以抽象出这个黑客:
def eval(code: String) = {
val toolbox = currentMirror.mkToolBox()
toolbox.eval(toolbox.parse("val $scope = scala.xml.TopScope; " + code))
}
现在看来:
scala> eval("<a>b</a>")
res24: Any = <a>b</a>