Używanie załączników z makrami w Scala 2.10
Aktualizacja: Podejrzewam, że to, czego chcę, może nie być możliwe i napisałem post na blogu z moim rozumowaniem (i kilkoma alternatywami)tutaj. Byłbym bardzo szczęśliwy, gdy dowiem się, że się mylę.
Załóżmy, że chcę utworzyć instancję cechy przy użyciu metody fabrycznej z implementacją makra. Ta metoda przyjmie jako argument ścieżkę do zasobu, które makro odczyta i przeanalizuje (w czasie kompilacji) na mapę ze łańcuchów do łańcuchów.
Ta część jest dość prosta. Załóżmy teraz, że chcę skojarzyć mapę wynikową z instancją, którą tworzę, aby móc z niej korzystać w kolejnych wywołaniach makr obejmujących tę instancję.
Najważniejszenie rób chcesz, aby mapa była członkiem instancji lub istniała w dowolnej formie w czasie wykonywania. Nie chcę też analizować tego samego zasobu więcej niż raz. Oto szkic tego, do czego dążę:
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. */ ???
}
To wydaje się być coś takiegozałączniki są przeznaczone do pomocy (dziękiEugene Burmako dlawskaźnik), a ja mam implementację opartą na załącznikach, która pozwala mi napisać:
Foo("whatever.txt").lookup("x")
Gdzieapply_impl
dołącza mapę do drzewa ilookup_impl
czyta ten załącznik z tego samego drzewa, które widzi jako przedrostek. Niestety jest to mniej lub bardziej bezużyteczne, ponieważ nie działa wfoo.lookup("x")
case, gdzie drzewo prefiksu jest tylko zmiennąfoo
.
(Zauważ, że w moim prawdziwym przypadku użyciaFoo
rozciąga sięDynamic
i próbuję podać implementację makra dlaselectDynamic
zamiastlookup
, ale to nie powinno być istotne tutaj - interesuje mnie ogólny przypadek.)
Czy jest jakiś sposób, aby użyć załączników, aby uzyskać to, czego chcę? Czy jest jakieś inne podejście, które byłoby bardziej odpowiednie?