我目前正在研究一些elixir宏有趣的东西。我有一个这样的模块:
defmodule MapUtils do
@handlers "I don't want you"
defmacro __using__(_) do
quote do
import MapUtils
Module.register_attribute __MODULE__, :handlers, accumulate: true
@handlers "I want you"
end
end
defmacro test do
IO.inspect @handlers
quote do
IO.inspect(@handlers)
end
end
end
defmodule Test do
use MapUtils
def testowa do
MapUtils.test
end
end
Test.testowa
结果如下:
"I don't want you"
["I want you"]
我想从报价块之外的调用者模块访问@handler,以根据它生成一些代码。据我所知,第一次检查正在执行,第二次正在转换为AST,并在不同的背景下执行。
有没有办法在编译时从调用者模块访问@handlers?
答案 0 :(得分:1)
如果我理解你的问题,你想要这个:
Module.register_attribute __MODULE__, :handlers,
accumulate: true,
persist: true
改变之前:
iex(6)> Test.module_info(:attributes)
[vsn: [95213125195364189087674570096731471099]]
改变后:
iex(13)> Test.module_info(:attributes)
[vsn: [95213125195364189087674570096731471099], handlers: ["I want you"]]
答案 1 :(得分:1)
我偶然发现this。
我意识到我可以像__CALLER__
那样叫它:
Module.get_attribute(__CALLER__.module, :handlers)
实际上它返回了它想要返回的值。