我有一个名为Interfaces的模块:
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
答案 0 :(得分:1)
我强烈建议您阅读Elixir官方网站上的Macros Guide。尽管您正在做的事情是可能的(使用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
这是我的一个项目中的another example,内容涉及如何使用辅助函数和其他宏来分解大型宏的实现。