2

I'm trying to write the macro that generates a module:

    defmodule GenModules do
       defmacro module(name, do: body) do
           quote do
               defmodule unquote(String.to_atom(name)) do                
                   unquote(body)
               end
           end
       end
    end

What I'm missing is to how to inject the 'import' statement that would refer the module the macro will be called from?

I.e., the following code:

    defmodule Test do
      import GenModules

      module "NewModule" do
        def test_call do
            hello_world
        end
      end

      def hello_world do
        IO.puts "Hello"
      end
    end   

won't compile because hello_world function is not visible from the generated NewModule.

So I need to generate

    import Test

before the body of the module, somehow getting the name of the module the macro was called from. How do I do this?

Thank you, Boris

1 Answer 1

1

To get the module your macro was called from you can use the special form __CALLER__. It contains a bunch of information, but you can extract the calling module like so:

__CALLER__.context_modules |> hd

But more generally I don't think what you want is possible - you cannot import a module before you finish defining it. For example:

defmodule A do
  defmodule B do
    import A
  end
end

results in an error:

** (CompileError) test.exs:3: module A is not loaded but was defined.
This happens because you are trying to use a module in the same context it is defined.
Try defining the module outside the context that requires it.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for that. Yes, I realized I couldn't do the import the way I planned. Still I think I can use the module name to replace calls such as hello_world to Mod.hello_world, once I get Mod value using the method you suggested.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.