6

更新:私が望んでいることは不可能かもしれないと思うので、ここに私の推論 (およびいくつかの代替案) をブログに投稿しまし。私が間違っていると言われたらとてもうれしいです。


ファクトリ メソッドとマクロ実装を使用して、特性のインスタンスを作成したいとします。このメソッドは、マクロが読み取り、(コンパイル時に) 文字列から文字列へのマップに解析するリソースへのパスを引数として取ります。

その部分はすべてかなり簡単です。ここで、結果のマップを作成中のインスタンスに関連付けて、そのインスタンスに関連する後続のマクロ呼び出しで使用できるようにしたいとします。

マップをインスタンスのメンバーにしたり、実行時に何らかの形で存在させたりしたくありません。また、同じリソースを複数回解析したくありません。これが私が目指している種類のスケッチです:

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マクロ実装を提供しようとしていることに注意してください。ただし、それはここでは関係ありません。一般的なケースに関心があります。)selectDynamiclookup

添付ファイルを使用して必要なものを取得する方法はありますか? より適切な他のアプローチはありますか?

4

1 に答える 1