Erlang/Elixir unquote 的地方有一处看不太懂,求解释

zztczcx · 2015年02月02日 · 最后由 pynix 回复于 2015年09月12日 · 2369 次阅读
defmacro defkv(kv) do
  quote do
    Enum.each unquote(kv), fn {k, v} ->
      def unquote(k)(), do: unquote(v)
    end
  end
end
If you try to run our new macro, you will notice it won’t even compile, complaining that the variables k and v does not exist. This is because of the ambiguity: unquote(k) can either be an unquote fragment, as previously, or a regular unquote as in unquote(kv).

文档里有一处修改是这样的, 这里的 ambiguity 怎么理解? 这两种情况是什么?

错误是由于 k, v 在上下文没有定义

猜测上面所说的两种情况是指

  1. unquote(kv),插入变量值
  2. unquote(ast),插入一段代码 宏是一种编译时代码变换/插入技术,可以详细读读 http://www.theerlangelist.com/2014/07/understanding-elixir-macros-part-6.html

#1 楼 @hhkbp2 那个时候刚开始学,不是很清楚,后来写了一些 macro 之后,有一点认识, 虽然现在可能也不是很清楚。 说下我现在的理解吧:

因为这里 quote do 返回的是一个 Enum.each 的结构, 这时并没有去执行 each 的操作,所以 k, v 在 macro unquote 的时候是未定义的。

这里有两种解决方法, 一种是在 defmacro 的时候 用 Enum.map, 而不是在 quote do 里面使用 Enum.map

第二种 就是 使用 bind_quoted: 这个选项, 这个时候 你会发现 最终返回的 ast 是带着 kv 信息的。

还是 ruby 一样的源码级别的 eval 比较容易懂。。。。

需要 登陆 后方可回复, 如果你还没有账号请 注册新账号