更新:私が望んでいることは不可能かもしれないと思うので、ここに私の推論 (およびいくつかの代替案) をブログに投稿しました。私が間違っていると言われたらとてもうれしいです。
ファクトリ メソッドとマクロ実装を使用して、特性のインスタンスを作成したいとします。このメソッドは、マクロが読み取り、(コンパイル時に) 文字列から文字列へのマップに解析するリソースへのパスを引数として取ります。
その部分はすべてかなり簡単です。ここで、結果のマップを作成中のインスタンスに関連付けて、そのインスタンスに関連する後続のマクロ呼び出しで使用できるようにしたいとします。
マップをインスタンスのメンバーにしたり、実行時に何らかの形で存在させたりしたくありません。また、同じリソースを複数回解析したくありません。これが私が目指している種類のスケッチです:
import scala.language.experimental.macros
import scala.reflect.macros.Context
trait Foo {
def lookup(key: String): String = macro Foo.lookup_impl
}
object Foo {
def parseResource(path: String): Map[String, String] = ???
def apply(path: String): Foo = macro apply_impl
def apply_impl(c: Context)(path: c.Expr[String]): c.Expr[Foo] = {
import c.universe._
val m = path.tree match {
case Literal(Constant(s: String)) => parseResource(s)
}
val tree = reify(new Foo {}).tree
// Somehow associate the map with this tree here.
c.Expr(tree)
}
def lookup_impl(c: Context)(key: c.Expr[String]): c.Expr[String] =
/* Somehow read off the map and look up this key. */ ???
}
これは、添付ファイルが役立つように設計されているようなものであるようです(ポインターについてはEugene Burmakoに感謝します)。次のように記述できる添付ファイルベースの実装があります。
Foo("whatever.txt").lookup("x")
Whereapply_impl
はマップをツリーにlookup_impl
アタッチし、そのアタッチメントを同じツリーから読み取ります。これをプレフィックスと見なします。残念ながら、これは多かれ少なかれ役に立ちませんfoo.lookup("x")
。ただし、プレフィックス ツリーが単なる変数である場合には機能しないためですfoo
。
(私の実際の使用例でFoo
は extendsであり、代わりに のDynamic
マクロ実装を提供しようとしていることに注意してください。ただし、それはここでは関係ありません。一般的なケースに関心があります。)selectDynamic
lookup
添付ファイルを使用して必要なものを取得する方法はありますか? より適切な他のアプローチはありますか?