Skip to content

Instantly share code, notes, and snippets.

@darui00kara
Last active April 12, 2017 13:39
Show Gist options
  • Save darui00kara/eddf82011b1d99dd166ffb1438b0343b to your computer and use it in GitHub Desktop.
Save darui00kara/eddf82011b1d99dd166ffb1438b0343b to your computer and use it in GitHub Desktop.
[elixir]map and ast toy
defmodule MacroExample do
alias User
alias Post
defmacro get_struct_info(
{:%, _, [{_, _, struct_name}, {:%{}, _, values}]}) do
quote do
{unquote(struct_name), unquote(values)}
end
end
def user(name, email) do
get_struct_info %User{name: name, email: email}
end
def post(title, body) do
get_struct_info %Post{title: title, body: body}
end
end
iex> user = %User{name: "hoge", email: "hoge@test.com"}
%User{email: "hoge@test.com", name: "hoge"}
iex> %User{user | name: "huge"}
%User{email: "hoge@test.com", name: "huge"}
iex> quote do: %User{user | name: "huge"}
{:%, [],
[{:__aliases__, [alias: false], [:User]},
{:%{}, [], [{:|, [], [{:user, [], Elixir}, [name: "huge"]]}]}]}
iex> module_name = :User
:User
iex> struct_value = :user
:user
iex> name = "huge"
"huge"
iex> q = {:%, [], [{:__aliases__, [alias: false], [module_name]}, {:%{}, [], [{:|, [], [{struct_value, [], Elixir}, [name: name]]}]}]}
{:%, [],
[{:__aliases__, [alias: false], [:User]},
{:%{}, [], [{:|, [], [{:user, [], Elixir}, [name: "huge"]]}]}]}
iex> Macro.to_string(q)
"%User{user | name: \"huge\"}"
iex> quote do: {:%, [], [{:__aliases__, [alias: false], [module_name]}, {:%{}, [], [{:|, [], [{struct_value, [], Elixir}, [name: name]]}]}]}
{:{}, [],
[:%, [],
[{:{}, [], [:__aliases__, [alias: false], [{:module_name, [], Elixir}]]},
{:{}, [],
[:%{}, [],
[{:{}, [],
[:|, [],
[{:{}, [],
[{:struct_value, [], Elixir}, [],
{:__aliases__, [counter: 0], [Elixir]}]},
[name: {:name, [], Elixir}]]]}]]}]]}
iex> quote do: unquote({:%, [], [{:__aliases__, [alias: false], [module_name]}, {:%{}, [], [{:|, [], [{struct_value, [], Elixir}, [name: name]]}]}]})
{:%, [],
[{:__aliases__, [alias: false], [:User]},
{:%{}, [], [{:|, [], [{:user, [], Elixir}, [name: "huge"]]}]}]}
iex> %User{name: "hoge", email: "hoge@test.com"}
%User{email: "hoge@test.com", name: "hoge"}
iex> quote do: %User{name: "hoge", email: "hoge@test.com"}
{:%, [],https://gist.github.com/darui00kara/eddf82011b1d99dd166ffb1438b0343b/edit
[{:__aliases__, [alias: false], [:User]},
{:%{}, [], [name: "hoge", email: "hoge@test.com"]}]}
iex> MacroExample.user "hoge", "hoge@test.com"
{[:User], [name: "hoge", email: "hoge@test.com"]}
iex> MacroExample.post "hogehoge", "foobar"
{[:Post], [title: "hogehoge", body: "foobar"]}
defmodule Post do
defstruct [:title, :body]
end
defmodule User do
defstruct [:name, :email]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment