在__using___中定义另一个宏



我有一个名为接口的模块:

defmodule Interfaces do
defmacro __using__(module) do
@module unquote(module) |> List.first |> elem(1)
defmacro expose(name) do
IO.inspect params, label: "Expanding macro with: "
IO.inspect @module, label: "I need this !!"
def unquote(name)() do
IO.puts "The function has been created with exposed name"
end
end
end
end

另一个模块名为Interfaces.MyModule:

defmodule Interfaces.MyModule do
use Interfaces, for: Something.DefinedElseWhere
expose :plop
end

但在编译时我得到了

** (CompileError) lib/my_module.ex:6: undefined function expose/1

我强烈建议您阅读Elixir官方网站上的宏指南。虽然你正在做的事情是可能的(使用quote(,但根本不鼓励你这样做。

宏应该很简单,如果需要,它们的功能应该在其他宏和方法中进一步分解一种方法是在宏中使用import语句导入其他需要在最终模块中公开的宏:

defmodule Interface do
defmacro __using__(opts) do
quote(bind_quoted: [opts: opts]) do
import Interface
@interface_module Keyword.get(opts, :for)
end
end
defmacro expose(name) do
quote do
IO.inspect @interface_module, label: "I need this !!"
def unquote(name)() do
IO.puts "The function has been created with exposed name"
end
end
end
end

现在您可以使用它:

defmodule MyImplementation do
use Interface, for: AnotherModule
expose(:hello)
end

这是我的一个项目中的另一个例子,关于如何使用辅助函数和其他宏分解大型宏的实现

最新更新