【问题标题】:Can I expand a macro inside a quote of another macro in Elixir?我可以在 Elixir 中另一个宏的引用中扩展宏吗?
【发布时间】:2020-05-29 22:20:09
【问题描述】:

鉴于以下代码,use Composite, user_opts: user_opts 行在 using(opts) as 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】:

回答所说的问题:完全可以从其他宏内部调用宏,最后只需递归注入 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

也就是说,您的问题是诱发的。


旁注: [{: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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多