Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Last active December 14, 2015 08:29
Show Gist options
  • Select an option

  • Save sasa1977/5057944 to your computer and use it in GitHub Desktop.

Select an option

Save sasa1977/5057944 to your computer and use it in GitHub Desktop.
defmodule RecordHelper.DynGenerator do
defmacro __using__(_) do
generate_macros
end
defp generate_macros do
Enum.map(1..20, fn(i) -> def_macro(args(i)) end)
end
defp def_macro(args) do
quote do
defmacro fields(unquote_splicing([quote(do: record) | args])) do
define_fields(record, [unquote_splicing(args)])
end
end
end
defp args(n) do
Enum.map(1..n, fn(i) -> {binary_to_atom("arg#{i}"), [], nil} end)
end
end
defmodule RecordHelper do
use RecordHelper.DynGenerator
defp define_fields(record, args) do
quote do
unquote(record)[unquote(Enum.map(args, function(:field, 1)))]
end
end
defp field({field, pattern}) do
quote do
{unquote(field), unquote(pattern)}
end
end
defp field(name), do: field({elem(name, 0), name})
end
defrecord MyRecord, [:a, :b]
defmodule Test do
import RecordHelper
def myfun(fields(MyRecord, a, {:b, nil})) do
IO.puts "a=#{a}"
end
def myfun(fields(MyRecord, a, b)) do
IO.puts "a=#{a}, b=#{b}"
end
def run do
myfun(MyRecord.new(a: 1, b: 2))
myfun(MyRecord.new(a: 1))
end
end
Test.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment