I will definitely go with binds quote. However, even when Macro.escape(%{}) is used the same error occurs. I really want to understand why, do you have any clues?
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
You’re double escaping which is what Jose meant by “don’t escape it again”. This works correctly:
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: %{:correct => true}
end
Yeah it’ll be more easy to understand if you do:
defmodule Foo do
defmacro __using__(options) do
options |> IO.inspect
attrs = Keyword.get(options, :attrs, Macro.escape(%{}))
quote do
def show, do: IO.inspect(unquote(attrs))
end
end
end
What you’ll see is that options comes through with {:%{}, [], [correct: true]} because it’s coming in as AST. So your issue is with the default value you have on Keyword.get. If no options are supplied you were returning an actual map, not map AST.