檢視原始碼 文件

Erlang 中的文件透過 -moduledoc-doc 屬性來完成。例如

-module(arith).
-moduledoc """
A module for basic arithmetic.
""".

-export([add/2]).

-doc "Adds two numbers.".
add(One, Two) -> One + Two.

-moduledoc 屬性必須位於第一個 -doc 屬性或函數宣告之前。它記錄模組的整體用途。

-doc 屬性總是位於其記錄的函數屬性之前。可以記錄的屬性是使用者定義的型別-type-opaque)和行為模組屬性-callback)。

預設情況下,用於文件屬性的格式是 Markdown,但可以透過設定模組文件元數據來變更。

開始編寫 Markdown 的一個好起點是 基本寫作和格式化語法

有關允許作為 -moduledoc-doc 屬性一部分的詳細資訊,請參閱文件屬性

-doc 屬性自 Erlang/OTP 27 起可用。

文件元數據

可以將元數據新增到文件項目。您可以透過新增以映射作為引數的 -moduledoc-doc 屬性來執行此操作。例如

-module(arith).
-moduledoc """
A module for basic arithmetic.
""".
-moduledoc #{since => "1.0"}.

-export([add/2]).

-doc "Adds two numbers.".
-doc(#{since => "1.0"}).
add(One, Two) -> One + Two.

元數據由文件工具使用,以向使用者提供額外的資訊。可以有多個元數據文件項目,在這種情況下,映射將被合併,如果存在重複的鍵,則以最新的優先。例如

-doc "Adds two numbers.".
-doc #{since => "1.0", author => "Joe"}.
-doc #{since => "2.0"}.
add(One, Two) -> One + Two.

這將產生一個 #{since => "2.0", author => "Joe"} 的元數據項目。

元數據映射中的鍵和值可以是任何類型,但建議僅使用原子作為鍵,並使用字串作為值。

外部文件檔案

-moduledoc-doc 也可以放在外部檔案中。若要這樣做,請使用 -doc {file, "path/to/doc.md"} 來指向文件。使用的路徑相對於 -doc 屬性所在的檔案。例如

%% doc/add.md
Adds two numbers.

%% src/arith.erl
-doc({file, "add.md"}).
add(One, Two) -> One + Two.

記錄模組

模組描述應包括如何使用 API 的詳細資訊以及不同函數協同工作的範例。這裡是一個很好的地方可以使用圖像和其他圖表來更好地展示模組的用法。與其在 moduledoc 屬性中撰寫長篇文字,不如將其分解到一個外部頁面中。

moduledoc 屬性應以簡短的段落描述模組開始,然後再深入介紹更多詳細資訊。例如

-module(arith).
-moduledoc """
   A module for basic arithmetic.

   This module can be used to add and subtract values. For example:

   ```erlang
   1> arith:substract(arith:add(2, 3), 1).
   4
   ```
   """.

Moduledoc 元數據

對於 -moduledoc,有三個保留的元數據鍵

  • since - 顯示新增模組的應用程式版本。如果新增此項,則除非在函數、型別或回呼的元數據中指定,否則其中的所有函數、型別和回呼也將收到相同的 since 值。
  • deprecated - 在文件中顯示說明它已過時以及改用什麼的文字。
  • format - 用於此模組中所有文件的格式。預設值為 text/markdown。應該使用格式的 mime 類型來編寫。

範例

-moduledoc {file, "arith.asciidoc"}.
-moduledoc #{since => "0.1", format => "text/asciidoc"}.
-moduledoc #{deprecated => "Use the Erlang arithmetic operators instead."}.

記錄函數、使用者定義型別和回呼

可以使用 -doc 屬性來記錄函數、型別和回呼。每個項目都應以簡短的段落描述實體的用途開始,然後再在需要時深入介紹更多詳細資訊。

不建議在此文件中包含圖像或圖表,因為 IDE 和 c:h/1 會使用它來向使用者顯示文件。

例如

-doc """
A number that can be used by the arith module.

We use a special number here so that we know
that this number comes from this module.
""".
-opaque number() :: {arith, erlang:number()}.

-doc """
Adds two numbers.

### Example:

```
1> arith:add(arith:number(1), arith:number(2)). {number, 3}
```
""".
-spec add(number(), number()) -> number().
add({number, One}, {number, Two}) -> {number, One + Two}.

Doc 元數據

對於 -doc,有四個保留的元數據鍵

  • since => unicode:chardata() - 顯示新增模組的應用程式版本。

  • deprecated => unicode:chardata() - 在文件中顯示說明它已過時以及改用什麼的文字。如果存在將函數標記為已過時的 -deprecated 屬性,編譯器將自動插入此鍵。

  • equiv => unicode:chardata() | F/A | F(...) - 註明此函數等效於此模組中的另一個函數。可以使用 Func/ArityFunc(Args)unicode 字串來描述等效性。例如

    -doc #{equiv => add/3}.
    add(One, Two) -> add(One, Two, []).
    add(One, Two, Options) -> ...

    -doc #{equiv => add(One, Two, [])}.
    -spec add(One :: number(), Two :: number()) -> number().
    add(One, Two) -> add(One, Two, []).
    add(One, Two, Options) -> ...

    進入 EEP-48 文件區塊元數據的項目是轉換為字串的值。

  • exported => boolean() - 一個 boolean/0,表示該項目是否已 exported。此值由編譯器自動設定,不應由使用者設定。

Doc 簽章

文件簽章是一個簡短的文字,用於描述函數及其引數。預設情況下,它是透過檢視 -spec 或函數中的引數名稱來決定的。例如

add(One, Two) -> One + Two.

-spec sub(One :: integer(), Two :: integer()) -> integer().
sub(X, Y) -> X - Y.

將具有 add(One, Two)sub(One, Two) 的簽章。

對於型別或回呼,簽章衍生自型別或回呼規範。例如

-type number(Value) :: {number, Value}.
%% signature will be `number(Value)`

-opaque number() :: {number, number()}.
%% signature will be `number()`

-callback increment(In :: number()) -> Out.
%% signature will be `increment(In)`

-callback increment(In) -> Out when In :: number().
%% signature will be `increment(In)`

如果無法從程式碼中「輕鬆」找出一個好的簽章,則會改用 MFA 語法。例如:add/2number/1increment/1

可以透過將自訂簽章放在 -doc 屬性的第一行來提供自訂簽章。提供的簽章必須採用函數宣告的形式,直到 -> 為止。例如

-doc """
add(One, Two)

Adds two numbers.
""".
add(A, B) -> A + B.

將建立簽章 add(One, Two)。簽章將從文件字串中刪除,因此在上面的範例中,只有文字 "Adds two numbers" 將成為文件的一部分。這適用於函數、型別和回呼。

在 Markdown 中撰寫文件時,會自動在任何看起來像 MFA 的內嵌程式碼片段中找到連結。例如

-doc "See `sub/2` for more details".

如果目前模組中存在 sub/2 函數,則將建立指向該函數的連結。也可以使用 `sub/2` 作為連結目標。例如

-doc "See [subtract](`sub/2`) for more details".
-doc "See [`sub/2`] for more details".
-doc """
See [subtract] for more details

[subtract]: `sub/2`
""".
-doc """
See [subtract][1] for more details

[1]: `sub/2`
""".

上述範例會產生相同的連結。

連結也可以是其他實體

  • 遠端函數 - 使用 module:function/arity 語法。

範例

-doc "See `arith:sub/2` for more details".
  • 模組 - 使用 m 前綴寫入模組。使用錨點跳到模組中的特定位置。

範例

-doc "See `m:arith` for more details".
-doc "See `m:arith#anchor` for more details".
  • 型別 - 使用與本機/遠端函數相同的語法,但新增 t 前綴。

範例

-doc "See `t:number/0` for more details".
-doc "See `t:arith:number/0` for more details".
  • 回呼 - 使用與本機/遠端函數相同的語法,但新增 c 前綴。

範例

-doc "See `c:increment/0` for more details".
-doc "See `c:arith:increment/0` for more details".
  • 額外頁面 - 對於目前應用程式中的額外頁面,請使用一般連結,例如 "[release notes](notes.md)"。對於另一個應用程式中的額外頁面,請使用 e 前綴並說明該頁面所屬的應用程式。也可以使用錨點跳到頁面中的特定位置。

範例

-doc "See `e:stdlib:unicode_usage` for more details".
-doc "See `e:stdlib:unicode_usage#notes-about-raw-filenames` for more details".

可見與隱藏的內容是什麼?

Erlang 應用程式 通常由各種公用和私有模組組成。也就是說,其他應用程式應使用的模組和不應使用的模組。預設情況下,應用程式中的所有模組都是可見的,但透過設定 -moduledoc false.,可以將特定模組隱藏而不列為可用 API 的一部分。

Erlang 模組由公用和私有函數以及型別屬性組成。預設情況下,所有匯出的函數、匯出的型別和回呼都被認為是可見的,並且是模組公用 API 的一部分。此外,任何其他可見型別屬性引用的非匯出型別也是可見的,但不被視為公用 API 的一部分。例如

-export([example/0]).

-type private() :: one.
-spec example() -> private().
example() -> one.

在上面的程式碼中,函數 example/0 已匯出,並且它引用了未匯出的型別 private/0。因此,example/0private/0 都將標記為可見。private/0 型別將具有設定為 false 的元數據欄位 exported,以顯示它不是公用 API 的一部分。

如果您想要讓可見的實體隱藏,則需要將 -doc 屬性設定為 false。讓我們重新檢視之前的範例

-export([example/0]).

-type private() :: one.
-spec example() -> private().
-doc false.
example() -> one.

函數 example/0 已匯出,但明確標記為隱藏;因此 example/0private/0 都將被隱藏。

新增到自動隱藏實體(非匯出函數或型別)的任何文件都將被忽略並產生警告。可以使用註解來記錄此類函數。

編譯和取得文件

編譯 Erlang 模組時,Erlang 編譯器預設會將文件插入 EEP-48 文件區塊。透過將 no_docs 標誌傳遞給 compile:file/1,或將 +no_docs 傳遞給 erlc,則不會插入任何文件區塊。

然後可以使用 code:get_doc/1 擷取文件,或使用 shell 內建命令 h/1 查看文件。例如

1> h(arith).

      arith

  A module for basic arithmetic.

2> h(arith, add).

      add(One, Two)

  Adds two numbers.

使用 ExDoc 產生 HTML/ePub 文件

ExDoc 內建支援從 Markdown 產生文件。最簡單的方法是使用 rebar3_ex_doc 外掛程式。若要設定 rebar3 專案以使用 ExDoc 產生文件,請將下列內容新增至您的 rebar3.config

%% Enable the plugin
{plugins, [rebar3_ex_doc]}.

{ex_doc, [
  {extras, ["README.md"]},
  {main, "README.md"},
  {source_url, "https://github.com/namespace/your_app"}
]}.

設定完成後,您可以執行 rebar3 ex_doc 將文件產生到 doc/index.html。如需更多詳細資訊和選項,請參閱 rebar3_ex_doc 文件。

您也可以從 GitHub 下載最新的發布 escript 包,並從命令列執行它。關於使用 escript 的說明文件,可以透過執行 ex_doc --help 來找到。

如果您正在編寫將使用 ExDoc 來生成 HTML/ePub 的文件,強烈建議您閱讀其說明文件。