12

リフレクションがまだ初期段階だった頃、Scala 2.10.0マイルストーンの日に、REPLからのコードスニペットのツリーを表示するためにそれをどのように使用できるかについて質問しました。優れた答えは、私が尋ねたよりもさらに進んで、それらを使用してツリーを解析および評価する方法も示したので、先に進んで、今日行っていた小さなプロジェクトでそれを使用しようとしました。

残念ながら、そのように解析および評価されたコードは、REPL定義を認識していないようです。

scala> val x = 1
x: Int = 1

scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> val tb = scala.reflect.runtime.universe.runtimeMirror(
  getClass.getClassLoader).mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = ...

scala> tb.eval(tb.parse("x"))
scala.tools.reflect.ToolBoxError: reflective compilation has failed:

not found: value x

REPLで作成された定義を認識させる方法はありますか?

4

1 に答える 1

6

最近、型マクロをサポートするようにしようとしたときにreplを掘り下げたので、なぜそれが機能しないのかを説明する準備が整っています。それを機能させることが次のステップになります:)

repl に入力されたすべてのスニペットは、コンパイルされる前にボイラープレートにラップされることをご存知でしょう。したがって、その x は、奇妙な名前のパッケージ内のネストされたネストされたネストされたオブジェクトのフィールドになります。

どうやら、 repl は定義されたすべてのシンボルを追跡し、生成するボイラープレートとともに必要なインポートを挿入します。したがって、後続の行では、x が修飾されていないことがわかります。対照的に、ツールボックスは単純に repl のクラスローダーを再利用しますが、インポートについては何もしないため、失敗します。

回避策は、どうにかして repl を表すオブジェクトに到達し、定義されたシンボルについて尋ねてから、ツールボックスにフィードするコードに対応するインポートを生成することです。チケットを提出していただければ、2.10.1 のコード フリーズの狂気が終わった後 (おそらく今週の終わり) に、回避策をコーディングしようと思います。

于 2013-02-05T08:35:04.483 に答える