如何通过宏列出特定子模块的所有模块?

huangapple go评论61阅读模式
英文:

How to list all the modules of a certain submodule via macro?

问题

以下是要翻译的代码部分:

在我的项目的特定目录和子目录中有模块,我想通过宏在编译时解析并保存到变量中

defmodule MyApp.MySubmodules.Mod1 do
    @doc "this module does AA"
  #
end

defmodule MyApp.MySubmodules.Mod2 do
    @doc "this is for CC"
  #
end

# ...

defmodule MyApp.MySubmodules.Mod3 do
    @doc "something afdsafdsfds"

  #
end

defmodule MyApp.MySubmodules.Xyz.Mod4 do
    @doc "blah-blah-blah-blah"

  #
end

And

defmodule MyApp.MainModule do
  use MyModuleParse

end

This would create a module attribute via macro

@my_modules %{
    mod1: "this module does AA",
    mod2: "this is for CC",
    mod3: "something afdsafdsfds",
    xyz_mod4: "blah-blah-blah-blah"
}

The idea is to be able to enumerate certain modules **at the compile time** and present them to a user on an html page. And do it without having to do copy-paste manually into `MyApp.MainModule` each time I change, add or delete a module.

How to implement this?

Firstly, how to list all of the modules given a certain path -- `MyApp.MySubmodules`? Then, how to read `@doc` of one?

**Via a macro.**

希望这有助于您理解代码的翻译。如果您需要进一步的帮助,请随时提出问题。

英文:

There're modules in a certain directory and sub-directories of my project which I want to parse and save into a variable at compile time via a macro

defmodule MyApp.MySubmodules.Mod1 do
    @doc "this module does AA"
  #
end

defmodule MyApp.MySubmodules.Mod2 do
    @doc "this is for CC"
  #
end

# ...

defmodule MyApp.MySubmodules.Mod3 do
    @doc "something afdsafdsfds"

  #
end

defmodule MyApp.MySubmodules.Xyz.Mod4 do
    @doc "blah-blah-blah-blah"

  #
end

And

defmodule MyApp.MainModule do
  use MyModuleParse

end

This would create a module attribute via macro

@my_modules %{
    mod1: "this module does AA",
    mod2: "this is for CC",
    mod3: "something afdsafdsfds",
    xyz_mod4: "blah-blah-blah-blah"
}

The idea is to be able to enumerate certain modules at the compile time and present them to a user on an html page. And do it without having to do copy-paste manually into MyApp.MainModule each time I change, add or delete a module.

How to implement this?

Firstly, how to list all of the modules given a certain path -- MyApp.MySubmodules? Then, how to read @doc of one?

Via a macro.

答案1

得分: 1

如果你查看ex_doc包,你可以看到一些它们的技巧,包括Code.fetch_docs/1,例如:

iex> Code.fetch_docs(Integer)
{:docs_v1, 2, :elixir, "text/markdown",
 %{
   "en" => "Functions for working with integers.\n\nSome functions that " <> _etc
 }, %{},
 [
   {{:function, :digits, 2}, 171, ["digits(integer, base \\ 10)"],
    %{
      "en" => "Returns the ordered digits for the given `integer`..." <> _etc
    }, %{defaults: 1}},
   # ... etc...
 ]}

这可以输出大量信息,但我认为它包含了你需要的一切:@moduledoc部分首先出现,然后是每个函数的@doc块的列表。

你可能需要使用一些Code.ensure_loaded/1(或类似的函数)的调用,因为你的“summary”模块需要这些其他模块在执行此类内省之前被编译。

英文:

If you take a look at the ex_doc package, you can see some of their tricks, including Code.fetch_docs/1, e.g.

iex&gt; Code.fetch_docs(Integer)
{:docs_v1, 2, :elixir, &quot;text/markdown&quot;,
 %{
   &quot;en&quot; =&gt; &quot;Functions for working with integers.\n\nSome functions that &quot; &lt;&gt; _etc
 }, %{},
 [
   {{:function, :digits, 2}, 171, [&quot;digits(integer, base \\\\ 10)&quot;],
    %{
      &quot;en&quot; =&gt; &quot;Returns the ordered digits for the given `integer`...&quot; &lt;&gt; _etc
    }, %{defaults: 1}},
   # ... etc...
 ]}

That can output a LOT of information, but I think it has everything you need: the @moduledoc stuff is first, then it's followed by a list of the @doc blocks for each function.

You might need to use some calls to Code.ensure_loaded/1 (or its friends) because your "summary" module requires that these other modules be compiled BEFORE it can perform this kind of introspection on them.

huangapple
  • 本文由 发表于 2023年5月6日 22:42:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76189486.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定