elixir - 在 Elixir 中的引用 block 外部定义函数

标签 elixir metaprogramming ex-doc

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

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

这按预期工作,但由于 run 函数嵌套在 quote block 内,我无法使用 ExDoc 添加文档。我还想在外部定义 run 函数,因为我觉得这会让代码看起来更好。像这样的事情:

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.

关于elixir - 在 Elixir 中的引用 block 外部定义函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46252534/

相关文章:

serial-port - 读取串行输入,直到控制字符指示消息结束

Java解密RSA加密数据ArrayIndexOutOfBoundsException : too much data for RSA block

ruby - 在运行时创建ActiveRecord模型rails3

python - 我如何更改实例的 __cmp__ 函数(不在类里面)?

ruby - ruby block 中定义的常量的常量定义的上下文是什么?

documentation - 链接到 ExDoc 中的外部类型

elixir - Elixir 中如何避免嵌套 if 语句?

elixir - 如何在 elixir 中调用 :ets. fun2ms?