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}