在长生不老药中的引号块外定义函数

Define function outside quote block in elixir

我有一个简单的宏,可以将函数注入调用模块。

defmodule MyModule do
  defmacro __using__(_opts) do
    quote do
      def run do
        IO.puts "Hello world"
      end
    end
  end
end

这按预期工作,但由于 运行 函数嵌套在引号块内,我无法使用 ExDoc 添加文档。我还想在外部定义 运行 函数,因为我觉得这样可以使代码看起来更好。像这样:

defmodule MyModule do
  def run do
    IO.puts "Hello world"
  end

  defmacro __using__(_opts) do
    quote do
       # Some code to inject the run function
    end
  end
end

我该怎么做?此外,如何使用 ExDoc 为嵌套函数添加文档?

您可以在 quote 中使用 defdelegate,然后在主模块中定义 run

defmodule MyModule do
  @doc """
  Prints "Hello world"
  """
  def run do
    IO.puts "Hello world"
  end

  defmacro __using__(_opts) do
    quote do
      defdelegate run, to: MyModule
    end
  end
end

defmodule A do
  use MyModule
end

A.run/0 将默认获得一个自动生成的文档,它将用户指向 MyModule.run/0。如果需要,可以通过在 defdelegate 之前添加 @doc "" 来自定义。

iex(1)> MyModule.run
Hello world
:ok
iex(2)> A.run
Hello world
:ok
iex(3)> h(MyModule.run)

                                   def run()

Prints "Hello world"

iex(4)> h(A.run)

                                   def run()

See MyModule.run/0.