Pass module into __using__, then use that module

Hey folks, newbie here to both the forum and using macros in Elixir. Trying to wrap my head around this situation:

I want this to be the API for the system I’m building:
use PoG.InternalAPI.Generator, schema: Rule.Val.API.Schema

In the __using__ callback for PoG.InternalAPI.Generator I essentially want to do this:

defmacro __using__([schema: schema]) do
  t = Macro.expand(schema, __ENV__)
  use t

The __using__ callback of Rule.Val.API.Schema injects module attributes necessary further down the macro in PoG.InternalAPI.Generator.__using__ but this doesn’t compile:

== Compilation error in file lib/internal_api/generator.ex ==
** (ArgumentError) invalid arguments for use, expected a compile time atom or alias, got: t

Am I fundamentally misunderstanding something?

Hey @mjlorenzo and welcome to Elixir Forum! :slight_smile:

While you don’t have a full example there so I’m not too sure what you’re returning, the important thing about macros is that they are just functions that take AST and return AST. In order to convert “regular” code to AST we use quote.

The TL;DR of what you’re looking for is:

defmacro __using__([schema: schema]) do
  quote do
    use unquote(schema)
  end
end
2 Likes