Использование вложений с макросами в Scala 2.10
Обновить: Я подозреваю, что то, что я хочу, может быть невозможным, и я написал сообщение в блоге со своими рассуждениями (и некоторыми альтернативами)Вот, Я был бы очень рад, если бы мне сказали, что я неправ.
Предположим, я хочу создать экземпляр свойства с использованием фабричного метода с реализацией макроса. Этот метод будет принимать в качестве аргумента путь к ресурсу, который макрос будет читать и анализировать (во время компиляции) в карту из строк в строки.
Эта часть довольно проста. Теперь предположим, что я хочу связать полученную карту с экземпляром, который я создаю, чтобы я мог использовать его в последующих вызовах макросов с этим экземпляром.
Я принципиальноне надо хотите, чтобы карта была членом экземпляра или существовала в любой форме во время выполнения. Я также не хочу анализировать один и тот же ресурс более одного раза. Вот эскиз того, к чему я стремлюсь:
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. */ ???
}
Это похоже на то, чтовложения предназначены, чтобы помочь с (спасибоЕвгений Бурмако зауказатель), и у меня есть реализация на основе вложений, которая позволяет мне написать следующее:
Foo("whatever.txt").lookup("x")
гдеapply_impl
прикрепляет карту к дереву иlookup_impl
читает это вложение из того же дерева, которое оно видит в качестве префикса. К сожалению, это более или менее бесполезно, так как это не работает вfoo.lookup("x")
случай, когда префиксное дерево является просто переменнойfoo
.
(Обратите внимание, что в моем реальном случае использованияFoo
продолжаетсяDynamic
и я пытаюсь дать реализацию макроса дляselectDynamic
вместоlookup
, но это не должно быть актуально здесь - меня интересует общий случай.)
Есть ли способ, которым я могу использовать вложения, чтобы получить то, что я хочу? Есть ли другой подход, который был бы более уместным?