I’m new to macros and I’m trying to do the following
defmodule Example do
use Ecto.Schema
compile_time_var = [foo: Foo, bar: Bar, baz: Baz]
schema "my_schema" do
# some macro magic here with `compile_time_var`
end
end
I’d like to use macros to have the module compile as if the schema looked like this
defmodule Example do
use Ecto.Schema
schema "my_schema" do
has_one :foo, Foo
has_one :bar, Bar
has_one :baz, Baz
end
end
But, I can’t figure out the right combination of quote
and unquote
to use with the compile time variable
You could also use bind_quoted as parameter, avoiding the need for unquote 
https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2
defmodule Example.MyMacro do
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
@opts opts
def foo do
IO.inspect "Inside #{__MODULE__}"
IO.inspect @opts, label: "OPTIONS"
end
end
end
end
defmodule Example.MySchema do
use Example.MyMacro, [foo: Foo, bar: Bar, baz: Baz]
end
# and run
iex(1)> Example.MySchema.foo
"Inside Elixir.Example.MySchema"
OPTIONS: [foo: Foo, bar: Bar, baz: Baz]
[foo: Foo, bar: Bar, baz: Baz]
Although I am not a big fan of shortcut like these.
1 Like
Turns out that I didn’t need a macro at all
defmodule Example do
use Ecto.Schema
compile_time_var = [foo: Foo, bar: Bar, baz: Baz]
schema "my_schema" do
for {field_name, type} <- compile_time_var do
has_one field_name, type
end
end
end
2 Likes