我可以在Elixir中的另一个宏的引号内扩展一个宏吗?

问题描述 投票:0回答:1

给出下面的代码,行use Composite, user_opts: user_opts在opts的using(opts)中以[{:user_opts, [line: 3, counter: {MockUserNode1, 2}], Automaton.Node}]结尾。有什么方法可以将代码插入外部宏中吗?

defmacro __using__(user_opts) do
    a =
      if Enum.member?(Composite.types(), user_opts[:node_type]) do
        IO.inspect(user_opts)

        quote bind_quoted: [user_opts: user_opts] do
          use DynamicSupervisor
          use Composite, user_opts: user_opts
        end
      else
        quote do: use(Action)
      end
end
macros elixir metaprogramming
1个回答
0
投票

回答上述问题:完全有可能从其他宏内部调用宏,最后只需递归注入AST。

defmodule DeeplyUsed do
  defmacro __using__(opts) do
    quote bind_quoted: [opts: opts] do
      opts
    end
  end
end

defmodule Used do
  defmacro __using__(opts) do
    quote bind_quoted: [opts: opts] do
      use DeeplyUsed, opts: opts
    end
  end
end

defmodule Using do
  use Used, line: 3, counter: {MockUserNode1, 2}
end

就是说,您的问题是诱人的。


Sidenote: [{:user_opts, _, Automaton.Node}]在那里确实非常可疑,这不是引述关键字列表的方式。首先显式取消引号记录在那里的user_opts

defmacro __using__(user_opts) do
  IO.inspect(user_opts, label: "Outside")
  quote do
    IO.inspect(unquote(user_opts), label: "Inside")
    use Composite, user_opts: unquote(user_opts)
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.