1
votes

I'm currently working on some elixir macro fun stuff. I have a module like that:

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

Which yields in such result:

"I don't want you"
["I want you"]

I want to access @handlers from callers module outside of the quote block to generate some code based on what it is. As far as my understanding goes first inspect is being executed and second is being transformed to AST and executed in differnt context.

Is there a way to get access to that @handlers from caller module in compile time?

2

2 Answers

1
votes

If I understand your question correctly, you want this:

Module.register_attribute __MODULE__, :handlers, 
                          accumulate: true,
                          persist: true

before the change:

iex(6)> Test.module_info(:attributes)
[vsn: [95213125195364189087674570096731471099]]

after the change:

iex(13)> Test.module_info(:attributes)
[vsn: [95213125195364189087674570096731471099], handlers: ["I want you"]]
1
votes

I stumbled upon this.

I realized I can call it with __CALLER__ like that:

Module.get_attribute(__CALLER__.module, :handlers)

And in fact it returned value it suppose to return.