将AST插入到引号中会在没有取消引用的情况下结束块

时间:2015-09-08 21:51:47

标签: metaprogramming elixir

window.location.hrefquote do end一起使用通常会提供一种将值注入AST的超级简单方法,从而避免遍历它。

这是一种情况。

unquote

但是,如果我不想插入引用的表达式ast = quote do 1 + 1 end quote do unquote(ast) |> manipulate_number end 的结果,而是插入AST 1 + 1,我发现自己将AST包含在另一个{:+, [context: Elixir, import: Kernel], [1, 1]}调用的AST中,像这样:

quote do end

还有其他办法吗?

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,以下应该按照你的意愿行事:

defmodule MacroExample do
  defmacro example(ast) do
    quoted = quote bind_quoted: [ast: ast] do
      ast + 3
    end
    IO.inspect Macro.to_string(quoted)
    quoted
  end
end

defmodule MacroTest do
  require MacroExample
  IO.inspect MacroExample.example(1 + 1)
end

结果在iex

iex> c "test.ex"
"(\n  ast = 1 + 1\n  ast + 3\n)"
5

我猜你的具体问题可能比推迟添加操作更复杂,如果上述不是你想要的,也许你想要完成的更现实的例子可以澄清问题和它的解决方案。

答案 1 :(得分:1)

如果要将AST原样注入另一个带引号的表达式,则需要Macro.escape/1。换句话说,你可以使用Macro.escape/1来确保某些引用的表达式在评估/展开时会自行返回。