Elixir:如何使用List作为变量定义多个宏?

时间:2016-05-15 09:10:25

标签: macros elixir

我正在尝试使用以下代码定义两个宏,但它失败了** (CompileError) iex:12: undefined function name/0。 函数参数name不能在defmacro的do块中取消引用。

这是什么原因? 有什么方法可以解决这个问题吗?

(Elixir版本为1.2.5)

defmodule IEx.MyHelpers do

  def default_env do
    __ENV__
  end

  [:functions, :macros] |> Enum.each(fn name ->
    defmacro unquote(name)(option \\ :all) do
      import MapSet
      quote do
        case unquote(option) do
          x when x in [:a, :all]      -> __ENV__     |> Map.take([unquote(name)])
          x when x in [:d, :default]  -> default_env |> Map.take([unquote(name)])
          x when x in [:i, :imported] ->
            difference(new(Map.take(__ENV__, [unquote(name)])),
                       new(Map.take(default_env, [unquote(name)])))
            |> MapSet.to_list
        end
      end
    end
  end)

end

1 个答案:

答案 0 :(得分:3)

您基本上需要取消引用两次,因为动态宏生成已经是隐式宏。您可以在defmacro

的顶部添加以下行
name = unquote(name)