I’m trying to understand how macros and module definitions interact with each others and I’m having few cases which I don’t understand. The below example has some pseudo doctest to show my doubts.
What I need is to support case 5. Thanks for the support in advance
defmodule Foo do
@doctest """
Case 1 OK: Trivial (and useless) case.. (Foo.Case1)
iex> Foo.Case1.foo
"local stuff"
Case 2 OK: Injects the Case2 in WrapMod and uses its args
WARNING: comment Case4 for this to work (head scratching)
iex> WrapMod.Case2.foo
[foo: "bar"]
Case 3 FAILED!!!! Injects used args into the Foo.Case3.foo function
Error:
example.ex:24: undefined function args/0 (expected Foo.Case3 to define
such a function or for it to be imported, but none are available)
Desiderata:
iex> Foo.Case3.foo
[foo: "bar"]
Case 4 KINDA NOT OK: Super clunky combo of case 2 and 1
It works, but it HIDES!!!!! Case 2: Call to `WrapMod.Case2.foo` is not available
anymore
iex> WrapMod.Case4.foo
"local stuff"
iex> WrapMod.Case2.foo
UndefinedFunctionError
Case 5 FAILED: Hyper clunky combo of case 2 with case 3 <- which is not working :(
This is where I'd want to get to: I would like to be able to invoke
and use the evaluated Foo.Case3.foo from within the quoted Case5 quoted module code
"""
defmacro __using__(args) do
#Case 1
defmodule Case1 do
def foo() do
"local stuff"
end
end
#Case 2
quote do
defmodule Case2 do
def foo() do
unquote(args)
end
end
end
#Case 3
#defmodule Case3 do
# def foo() do
# quote do
# unquote(args)
# end
# end
#end
# Case 4: comment me to get back WrapMod.Case2.foo which is otherwise no more available!!!
quote do
defmodule Case4 do
def foo() do
Case1.foo()
end
end
end
#quote do
# defmodule Case5 do
# def foo() do
# Case3.foo()
# end
# end
#end
end
end
defmodule WrapMod do
use Foo, foo: "bar"
end
For the records, case 3 works if I change it like this:
#Case 3
defmodule Case3 do
def foo() do
quote do
var!(args)
end
end
end
but this is giving me
iex(1)> Foo.Case3.foo
{:var!, [context: Foo.Case3, import: Kernel], [{:args, [], Foo.Case3}]}
which is clearly not what I want