For the life of me I can’t figure out how to read a attribute created in a macro:
example:
defmacro staticKV(key, value) do
quote do
Module.put_attribute(__MODULE__, unquote(key), unquote(Macro.escape(v)))
def value(unquote(key)), do: <<code to read the attribute defined above>>
end
end
I wanted to do this because I have some data files that I access a LOT (in many processes currently) and the values don’t change so I would like to not pay the cost of say loading it into ets, etc.
I have tried doing @unquote(key) but that will not compile and trying to use Module.get_attribute complains because it is not called at compile time. Any help would be greatly appreciated.
3 Likes
I should add I am on elixir 1.3.3.
1 Like
My goal here was to get the values into the literal heap space and I guess I didn’t need to mess around with setting it up as an attribute in my use case (verified via :compile.forms on the output beam data ), however if anyone has an answer to the above question it would be great to know.
1 Like
Attributes do not really persist as you expected, just putting the literal into the fun body will do it though. ^.^
A couple notes, instead of get_attribute you do want to use the @blah
syntax, however you need to key it ‘outside’ of your quote because the scoping rules for the @
form are a bit wonky, so this would do it by doing the raw AST:
defmacro staticKV(key, value) do
attr_ast = {:@, [], [{key, [], [value]}]
attr_use_ast = {:@, [], [{key, [], nil}]}
quote do
unquote(attr_ast)
def value(unquote(key)), do: unquote(attr_use_ast)
end
Or something like that (untested). But yeah as you have noticed, put the value in the def body directly, not as an attribute, and that makes it very re-usable to the system. ^.^
1 Like