Required inside a macro

I wrote a macro, and I want to use Logger.info in it, so i have to require Logger. What is the best practice to do this? Oblige the client to require Logger on its own, or add using macro and require Logger there.

According to the tutorials, require is lexically scoped. This means you are able to just put the require statement within your macro definition itself, and everything will work:

iex(1)> defmodule Foo do
...(1)>   defmacro bar do
...(1)>     require Logger
...(1)>     Logger.info("foobar")
...(1)>   end
...(1)> end

{:module, Foo, <<70, 79, 82, ...>>, {:bar, 0}}

iex(2)> defmodule Baz do
...(2)>   require Foo
...(2)>   Foo.bar
...(2)> end

20:26:12.017 [info]  foobar
{:module, Baz, <<70, 79, 82, ...>>, :ok}

This is probably not what the OP wants, as it will log during compile time.

The require and the call to logger have to be quoted, which again results in a “leaking” require.

I’d go for the option to properly document the dependency.

2 Likes

Or pass in the Logger module name into the function for it to call on. Though with something as common as Logger, maybe not (though it would allow for easy overriding it and so forth). ^.^;