Elixir 即使使用宏.escape,Unquoute也不适用于贴图

Elixir 即使使用宏.escape,Unquoute也不适用于贴图,elixir,Elixir,我有以下代码: defmodule Foo do defmacro __using__(options) do attrs = Keyword.get(options, :attrs, Macro.escape(%{})) quote do def show, do: IO.inspect(unquote(attrs)) end end end defmodule MacroBug do use Foo, attrs: Macro.esc

我有以下代码:

defmodule Foo do
  defmacro __using__(options) do
    attrs = Keyword.get(options, :attrs, Macro.escape(%{}))
    quote do
      def show, do: IO.inspect(unquote(attrs))
    end
  end
end

defmodule MacroBug do
  use Foo,
    attrs: Macro.escape(%{:correct => true})
end

此代码打印:

iex(5)> MacroBug.show
{:%{}, [], [correct: true]}
{:%{}, [], [correct: true]}
它应该是
%{correct:false}
,否?如果没有,正确的方法是什么?如中所示,应该显式地
宏.escape/2

在您的示例中,问题是您实际上引用了两次地图。检查这三个宏:

defmodule Escape do
DEFQ宏(选项)do
IO.检查(选项,标签:“报价”)
报价do:IO.inspect(取消报价(opts),标签:“取消报价”)
结束
定义宏(选项)do
value=IO.inspect(宏.escape(%{foo:%{}}),标签:“escape”)
报价do:IO.inspect(取消报价(值),标签:“unescape”)
结束
德福!(选择)做什么
value=IO.inspect(%%{foo:%%{},标签:“escape!”)
quote do:IO.inspect(unquote(值),标签:“unescape!”)
结束
结束
前两种方法是相当等价的,并且很乐意产生预期的结果

iex | 1▸ Escape.q%{foo:%{}
转义:{:%{},[],[foo:{:%{},[],[]}]}
unescape:%%{foo:%%{}
%{foo:%{}
iex | 2▸ Escape.q%{foo:%{}
引号:{:%{},[],[foo:{:%{},[],[]}]}
取消报价:%%{foo:%%{}
%{foo:%{}
但是,第三个会引发,因为不能通过AST转换边界传递
%{foo:%{}}
。也就是说,对于后一种情况,就像在宏上下文中创建的值一样,应该避开它


对于从宏外部传递的值,请为您完成所有操作。

感谢您的回复!我用一个最小的可重复的例子编辑了这个问题。根据您的问题,结果应该是
%{correct:false},
no?
attrs:Macro.escape(%{:correct=>true})
→ <代码>属性:%{:correct=>true}