Skip to content

Instantly share code, notes, and snippets.

@Lakret
Created June 14, 2019 12:51
Show Gist options
  • Save Lakret/fc7597bb526e3639fa4ef8088e14957f to your computer and use it in GitHub Desktop.
Save Lakret/fc7597bb526e3639fa4ef8088e14957f to your computer and use it in GitHub Desktop.
Replace `^variable` with the variable value with Elixir macro
defmodule Foo do
defmacro select(columns) when is_list(columns) do
# in macro context we replace all `^foo` forms with `foo`
columns = Macro.postwalk(columns, &interpolate/1)
IO.inspect(columns, label: :columns_after_interpolate)
# we unquote in the caller context, and map atoms to Columns after all
# `^foo` were replaced with `foo`
quote do
Enum.map(unquote(columns), &Foo.atom_to_column/1)
end
end
def interpolate({:^, _, [{name, _ctx, _env} = v]}) when is_atom(name) do
IO.inspect(v, label: :replaced_in_function)
v
end
def interpolate(x), do: x
# column conversion logic
defmodule Column do
defstruct [:name]
end
def atom_to_column(a) when is_atom(a) do
%Column{name: a}
end
def atom_to_column(a), do: a
end
import Foo
c = select([:foo, :bar])
bar = :foobar
c = select([:foo, ^bar])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment