我有一个格式为{:task, function_name, description}
的元组列表,我想生成一个调用元组中定义的函数来覆盖值的函数。
我生成的函数应如下所示:
def run(val) do
val = do_something(val)
val = do_something_else(val)
...
val
end
这是我目前的代码:
defmacro __before_compile__(env) do
steps = Module.get_attribute(env.module, :steps) |> Enum.reverse
iteration = Enum.map steps, fn {:task, func, _} ->
quote do
val = unquote(func)(val)
end
end
ast = quote do
def run(val) do
unquote(iteration)
val
end
end
ast
end
但是这会产生以下功能:
def(run(val)) do
[val = it_adds_five(val), val = it_adds_ten(val)]
val
end
如您所见,我的函数调用位于列表中,只应用了最后一个函数调用。当我将值2
传递给run
函数时,我会返回12
。
答案 0 :(得分:2)
您可以使用Kernel.SpecialForms.unquote_splicing/1
代替Kernel.SpecialForms.unquote/1
来拼接"拼接"在AST节点列表中。
更改:
def run(val) do
unquote(iteration)
val
end
到
def run(val) do
unquote_splicing(iteration)
val
end
生成此AST:
def(run(val)) do
val = bar(val)
val = foo(val)
val
end
的
@steps [
{:task, :foo, ""},
{:task, :bar, ""},
]