Я пытаюсь "шаблонизировать" некоторый избыточный код.Я могу заставить его генерировать предупреждения компилятора о неиспользуемых переменных, но я получаю «недопустимые выражения в кавычках» и пытаюсь использовать те же самые переменные.
defmodule Foo do
defmacro __using__(variables) do
quote do
def mapify(unquote(Enum.map(variables, &Macro.var(&1, nil))) do
# will yield compiler warnings about unused variables
%{}
# invalid quoted expression
unquote(Enum.map(variables, &{&1, Macro.var(&1, nil)}) |> Map.new)
end
end
end
end
Использование:
defmodule X do
use Foo, [:alpha, :bravo, :charlie]
end
Как я могу сгенерировать это?
defmodule X do
def mapify(alpha, bravo, charlie) do
%{alpha: alpha, bravo: bravo, charlie: charlie}
end
end
Эликсир 1.7.3, Эрланг 21.0
РЕДАКТИРОВАТЬ:
Это сгенерируетфункционально правильная версия, но меня беспокоит, что Enum.zip запускается при каждом вызове ...
defmodule Foo do
defmacro __using__(variables) do
vars = Enum.map(variables, &Macro.var(&1, nil))
result = quote do
def mapify(unquote(vars)) do
Enum.zip(unquote(variables), unquote(vars)) |> Map.new
end
end
IO.puts("Macro generated:\n#{result |> Macro.to_string}")
result
end
end
сгенерировано:
def(mapify([alpha, bravo, charlie])) do
Enum.zip([:alpha, :bravo, :charlie], [alpha, bravo, charlie]) |> Map.new()
end
РЕДАКТИРОВАТЬ:
Пойдем с этим, если кто-то не может понять исходный запрос:
defmodule Foo do
defmacro __using__(variables) do
vars = Enum.map(variables, &Macro.var(&1, nil))
pairs = Enum.map(variables, &{&1, Macro.var(&1, nil)})
result = quote do
def mapify(unquote(vars)) do
unquote(pairs) |> Map.new
end
end
IO.puts("Macro generated:\n#{result |> Macro.to_string}")
result
end
end
Сгенерированный макрос:
def(mapify([alpha, bravo, charlie])) do
[alpha: alpha, bravo: bravo, charlie: charlie] |> Map.new()
end