In file 1:
defmodule Utils.Struct do
# this is for importing definitions when "use Utils.Struct" is called
defmacro __using__(_opts) do
quote do
import Utils.Struct
end
end
defmacro defstruct_module(struct_name, fields) do
quote do
defmodule unquote(struct_name) do
use Utils.Access
defstruct unquote(fields)
end
end
end
end
In file 2:
defmodule Statistical.Generator do
use Utils.Struct
@in_files [:in_cause, :out_cause, :start]
defstruct_module(State, @in_files)
Breaks:
warning: undefined module attribute @in_files, please remove access to @in_files or explicitly set it before access
<some file>: Statistical.Generator.State (module)
== Compilation error in file <some file> ==
** (ArgumentError) struct fields definition must be list, got: nil
(elixir 1.14.4) lib/kernel/utils.ex:117: Kernel.Utils.defstruct/3
But this works - again file 2:
defmodule Statistical.Generator do
use Utils.Struct
@in_files [:in_cause, :out_cause, :start]
in_files = @in_files
defstruct_module(State, in_files)
By the way, if I use the variable approach instead of the module attribute, than the def blocks of the module in file 2 complain… can’t win? ![]()
Is this because the it inserts the module attribute verbatim as abstract syntax tree? Is there a construct/pattern to handle this case - like would a bind_quote help?
Thank you!


















