如何使Elixir中的unquote输出最小报价结果

时间:2018-09-27 16:22:23

标签: elixir

如何生成该表达式的输出

quote do
  defmodule X do
    unquote do
      IO.puts "working ..."
      args = [{:a, [], Elixir}, {:b, [], Elixir}]
      quote do
        def myfun(unquote_splicing(args)) do
        end
      end
    end
  end
end

working ...
{:defmodule, [context: Elixir, import: Kernel],
 [
   {:__aliases__, [alias: false], [:X]},
   [
     do: [ # <---- WANT TO REMOVE THIS
       do: {:def, [context: Elixir, import: Kernel],
        [
          {:myfun, [context: Elixir], [{:a, [], Elixir}, {:b, [], Elixir}]},
          [do: {:__block__, [], []}]
        ]}
     ] # <---- WANT TO REMOVE THIS
   ]
 ]}

与该表达式完全一样

quote do
  defmodule X do
    def myfun(a,b) do
    end
  end
end

{:defmodule, [context: Elixir, import: Kernel],
 [
   {:__aliases__, [alias: false], [:X]},
   [
     do: {:def, [context: Elixir, import: Kernel],
      [
        {:myfun, [context: Elixir], [{:a, [], Elixir}, {:b, [], Elixir}]},
        [do: {:__block__, [], []}]
      ]}
   ]
 ]}

我想知道如何修改第一个表达式以删除其输出中的信号线。

谢谢

1 个答案:

答案 0 :(得分:1)

该问题的答案是unquote需要一个表达式,而不是一个块。

我试图在unquote内进行过多的计算,因此我使用了unquote do ... end。但是,在这种情况下,我们应该:

  • 编写unquote(func(...))并在另一个函数中进行大量计算;

  • 在代码中的某个位置之前写unquote(data)并做data = func(...)

  • ,或者构建带引号的表达式。

上述问题的解决方案是最后一种选择(费尔南多·塔皮亚·里科在Unquote leaves a trace of its own in the resulting AST #8233中给出的解决方案):

args = [{:a, [], Elixir}, {:b, [], Elixir}]

fun_ast = quote do
  def myfun(unquote_splicing(args)) do
  end
end

quote do
  defmodule X do
    unquote(fun_ast)
  end
end