Hello!
I’m working with macros and I am trying to inject some code into a use
macro to be used “as-is” but I’m having some trouble making it work.
I would like to be able to define a __using__
macro which takes some options and creates a function that can use those options “as-is” i.e. if I pass Application.get_env(...)
it will get the env at the time of the call, something like
defmodule HypotheticMod do
# Let's assume this will create a foo function
# which returns the value of Application.get_env(:app, :foo, 0)
use InjectMacro, option: Application.get_env(:app, :foo, 0)
def get_foo_from_env(), do: foo()
end
The first version I tried was this
Application.delete_env(:app, :test)
defmodule Foo do
defmacro __using__(opts) when is_list(opts) do
foo = Keyword.get(opts, :foo)
quote do
def func() do
unquote(foo)
end
end
end
end
defmodule Bar do
a = 1
use Foo, foo: Application.get_env(:app, :test, a)
end
a = 2
Application.put_env(:app, :test, a)
Bar.func()
and I expected Bar.func()
to output 2
, but I get the following error:
function a/0 (expected Bar to define such a function or for it to be imported, but none are available)
Next I tried this
Application.delete_env(:app, :test)
defmodule Foo do
defmacro __using__(opts) when is_list(opts) do
foo = Keyword.get(opts, :foo)
quote bind_quoted: [foo: foo] do
def func() do
unquote(foo)
end
end
end
end
defmodule Bar do
a = 1
use Foo, foo: Application.get_env(:app, :test, a)
end
a = 2
Application.put_env(:app, :test, a)
Bar.func()
which returns 1
for some reason I don’t understand.
I am surely missing something, can anyone help me?
Thanks