我正在尝试编写帮助宏,它允许我编写一堆 Elixir 结构而没有很多样板,所以我写了宏:
defmodule Events do
@moduledoc false
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
defmodule unquote(module) do
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
可以按如下方式使用:
defmofule Event do
import Events
defevent Foo, foo: String.t(), bar: number()
end
但是,我想增加通过@doc模块属性向此类模块添加文档的可能性:
defmodule Events do
@moduledoc false
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
docs = Module.delete_attribute(__MODULE__, :doc)
defmodule unquote(module) do
for doc <- docs do
@moduledoc doc
end
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
但是,当没有文档或有文档字符串时,它不会作为Module.get_attribute(__MODULE__, :doc)返回值。但是它错过了所有标签,所以编写如下代码:nil{integer(), String.t()}
defmofule Event do
import Events
@doc "Foo"
@doc deprecated: "Bar"
defevent Foo, foo: String.t(), bar: number()
end
将只包含"Foo"没有指定标签的字符串。我目前的解决方法是使用自定义属性,但这不是最漂亮的解决方案,因为它需要非标准参数并定义自定义模块属性(这让我依赖use)。
defmodule Events do
@moduledoc false
defmacro __using__(_) do
quote do
import unquote(__MODULE__), only: [defevent: 1, defevent: 2]
Module.register_attribute(__MODULE__, :eventdoc, accumulate: true)
end
end
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
docs = Module.delete_attribute(__MODULE__, :eventdoc)
defmodule unquote(module) do
for doc <- docs do
@moduledoc doc
end
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
有没有办法获得@doc分配了所有属性的电流值?