Reputation: 15156
I'm playing with use
functionality in elixir. I can't understand one thing:
defmodule Alex do
use Included,
names: [:helen, :rebekka],
states: [
%{
:name => :start
}, [
name: :finish
]
end
I placed different constructors (map & keyword) just to show the difference. I have a simple elixir module which returns me a values:
defmodule Included do
demacro __using__(opts) do
IO.puts Keyword.get(opts, :names) # => [:helen, :rebekka]
IO.puts Keyword.get(:states) # => [{:%{}, [line: 8], [name: :start]}, [name: :finish]]
end
end
Why do I receive this strange map and how can I get normal maps in my module?
Upvotes: 2
Views: 344
Reputation: 54684
What you get is the AST representation of the opts
, just like any arguments that are passed to macros. If you are using proplists, these happen to take the same form in quoted an unquoted form:
iex> [name: :finish]
[name: :finish]
iex> quote do: [name: :finish]
[name: :finish]
Maps however don't, because they are not among the basic data types:
iex> %{name: :finish}
%{name: :finish}
iex> quote do: %{name: :finish}
{:%{}, [], [name: :finish]}
This is the reason why proplists are the preferred way to pass options to a macro. However, you can use an unquoted map within a quote
as expected:
defmodule Included do
defmacro __using__(opts) do
quote do
IO.inspect unquote(opts)
end
end
end
defmodule Alex do
use Included, %{name: :start}
end
This will simply print
%{name: :start}
Upvotes: 2