Update: I suspect that what I want may not be possible, and I wrote a blog post with my reasoning (and some alternatives) here . I would be very happy if they tell me that I'm wrong.
Suppose I want to instantiate an attribute using the factory method with a macro implementation. This method will take as an argument the path to the resource that the macro will read and parse (at compile time) into the map from line to line.
This part is pretty simple. Now suppose I want to associate the resulting map with an instance that I create so that I can use it in subsequent macro calls associated with this instance.
I absolutely do not want the card to be a member of the instance or exist in any form at run time. I also do not want to analyze the same resource more than once. Here is a sketch of the kind of thing I was aiming for:
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
It looks like attachments are for help (thanks to Eugene Burmako for a pointer ), and I have an attachment-based implementation that allows me to write the following:
Foo("whatever.txt").lookup("x")
Where apply_impl attaches the map to the tree, and lookup_impl reads this attachment from the same tree that it sees as its prefix. Unfortunately, this is more or less useless since it does not work in the case of foo.lookup("x") , where the prefix tree is just a foo variable.
(Note that in my real case of using foo extends Dynamic , and I'm trying to give a macro implementation for selectDynamic instead of lookup , but this should not be appropriate here: m interested in the general case.)
Is there a way I can use attachments to get what I want? Is there any other approach that would be more appropriate?
source share