文档指南¶ ↑
本指南讨论了在 Ruby 核心和 Ruby 标准库中记录类、模块和方法的建议。
生成文档¶ ↑
大多数 Ruby 文档都位于源文件中,并以 RDoc 格式 编写。
某些页面位于 doc
文件夹下,可以使用 .rdoc
或 .md
格式编写,由文件扩展名决定。
要在 {build folder}/.ext/html
目录中生成 HTML 中文档更改的输出,请在构建目录中运行以下内容
make html
如果没有构建目录,请按照 快速入门指南 执行步骤 4。
然后,可以通过在浏览器中打开 {build folder}/.ext/html/index.html
文件来预览更改。
目标¶ ↑
Ruby 文档的目标是在最短的时间内传达最重要和最相关的信息。读者应该能够快速理解主题代码的用途以及如何使用它。
提供的信息太少是不好的,但提供不重要的信息或不必要的示例也不是好的。根据用户的需要来判断。
一般准则¶ ↑
-
请记住,读者可能不会流利地使用英语。
-
写简短的陈述句或祈使句。
-
将句子分组为(理想情况下较短的)段落,每个段落涵盖一个主题。
-
使用 标题 组织材料。
-
使用 链接 引用权威和相关来源。
-
使用简单的时态:简单现在时、简单过去时、简单将来时。
-
使用简单的句子结构,而不是复合或复杂结构。
-
避免
字符¶ ↑
在 C 源文件中仅使用与 US-ASCII 兼容的字符。(如果你使用其他字符,Ruby CI 会温和地让你知道。)
如果想将与 ASCII 不兼容的字符放入 C 编码的类、模块或方法的文档中,可以使用涉及新文件 doc/*.rdoc
的解决方法
-
对于类
Foo
(在文件foo.c
中定义),创建文件doc/foo.rdoc
,声明class Foo; end
,并将类文档放在该声明之上# Documentation for class Foo goes here. class Foo; end
-
类似地,对于模块
Bar
(在文件bar.c
中定义),创建文件doc/bar.rdoc
,声明module Bar; end
,并将模块文档放在该声明之上# Documentation for module Bar goes here. module Bar; end
-
对于方法,情况有所不同。如上所述记录方法会禁用已渲染文档中的“单击切换源”功能。
因此,最好使用文件包含
-
保留 C 代码中的
call-seq
。 -
使用文件包含 (
:include:
) 以包含 .rdoc 文件中的文本。
示例
/* * call-seq: * each_byte {|byte| ... } -> self * each_byte -> enumerator * * :include: doc/string/each_byte.rdoc * */
-
RDoc¶ ↑
Ruby 使用 RDoc
进行文档化。有关 RDoc 语法和功能的信息,请参阅 RDoc 标记参考。
来自 irb
的输出¶ ↑
对于代码示例,请考虑使用交互式 Ruby,irb。
对于包含 irb
输出的代码示例,请考虑在连续的行中对齐 # => ...
。对齐有时可能有助于可读性
a = [1, 2, 3] #=> [1, 2, 3] a.shuffle! #=> [2, 3, 1] a #=> [2, 3, 1]
标题¶ ↑
使用 标题 来组织类或模块的冗长讨论。
不要在方法或常量的文档中使用正式标题。
在极少数情况下,需要在方法或常量的文档中使用标题状结构时,请使用 粗体文本 作为伪标题。
空行¶ ↑
空行开始一个新段落。
空行应该在 代码块 或 列表 之前和之后出现。对于 HTML 输出,这是不必要的,但有助于 ri
输出。
方法名称¶ ↑
对于文本中的方法名称
-
对于当前类或模块中的方法,对于单例方法使用双冒号,对于实例方法使用井号:
::bar
、#baz
。 -
否则,包括类或模块名称,并对于单例方法使用点,对于实例方法使用井号:
Foo.bar
、Foo#baz
。
嵌入式代码和命令¶ ↑
嵌入在运行文本中(即,不在代码块中)的代码或命令应该标记为 单字体。
作为简单字符串的代码应该包括引号。
自动链接¶ ↑
通常情况下,不应抑制 RDoc 的自动链接。例如,我们应该编写 Array
,而不是 \Array
。
我们可能会考虑在以下情况下抑制:
-
有疑问的单词不指代 Ruby 实体(例如,Class 或 English 的某些用法)。
-
引用的是当前类文档(例如,类
Array
的文档中的 Array)。 -
多次重复相同的引用(例如,本页上的 RDoc)。
-
引用的是用户通常不处理的类或模块,包括以下内容
-
Class。
-
Method。
-
Module。
-
大多数情况下,类、模块或方法的名称将自动链接
如果没有,或者如果您抑制自动链接,请考虑强制使用 单字体。
显式链接¶ ↑
编写显式链接时,请遵循以下准则。
rdoc-ref
架构¶ ↑
对以下内容使用 rdoc-ref
架构
-
核心文档中指向其他核心文档的链接。
-
核心文档中指向标准库包中文档的链接。
-
标准库包中指向该标准库包中其他文档的链接。
请参阅 链接 中的“rdoc-ref
架构”一节。
基于 URL 的链接¶ ↑
对以下内容使用基于 URL 的完整链接
-
标准库文档中指向核心文档的链接。
-
标准库文档中指向不同标准库包中文档的链接。
这样做可确保即使包文档独立构建(独立于核心文档),链接仍然有效。
链接应指向 docs.ruby-lang.org/en/master/ 中的目标。
对指向站外文档的链接也使用基于 URL 的完整链接。
变量名称¶ ↑
变量的名称(如其调用序列中指定的)应标记为 单字体。
此外,对临时变量的名称使用单字体文本(即,仅在讨论中定义和使用的变量,例如 n
)。
HTML 标记¶ ↑
通常,避免使用 HTML 标记(即使在允许使用的格式中),因为 ri
(Ruby 交互式参考工具)可能无法正确呈现它们。
表格¶ ↑
特别是,避免使用 HTML 标记(<table>
等)构建表格。
备选方案
-
(仅限 Markdown 格式):Github Flavored Markdown (GFM) 表格,使用文本的特殊格式
记录类和模块¶ ↑
类或模块文档的总体结构应为
-
概要
-
常见用法,附带示例
-
“此处内容”摘要(可选)
概要¶ ↑
概要是对类或模块的作用以及读者可能希望使用它的原因的简短描述。在概要中避免使用细节。
常见用法¶ ↑
展示类或模块的常见用法。根据类或模块的不同,此部分在长度和复杂性上可能会有很大差异。
此处内容摘要¶ ↑
类或模块的文档可能包含“此处内容”部分。
指南
-
部分标题为
此处内容
。 -
考虑列出父类和任何包含的模块;如果存在,请考虑将 链接 添加到它们的“此处内容”部分。
-
应列出目录表中左侧提到的所有方法(包括从其他类扩展的任何方法)。
-
也可以列出属性(不包含在目录中)。
-
将显示方法作为一项或多项项目符号列表中的项目
-
每项以方法名称开头,后跟冒号和简短描述。
-
如果方法有别名,请在冒号之前用括号注明(不要单独列出别名)。
-
检查呈现的文档以确定 RDoc 是否已识别方法并链接到该方法;如果没有,请手动插入 链接。
-
-
如果有多个条目,请考虑将它们分组到带标题的子部分中。
-
如果此类子部分超过几个,请考虑在主部分标题下方添加目录。
记录方法¶ ↑
常规结构¶ ↑
方法文档的常规结构应为
-
调用顺序(对于用 C 编写的函数)。
-
概要(简短描述)。
-
详细信息和示例。
-
参数描述(如果需要)。
-
特殊情况和异常。
-
相关方法(可选)。
调用顺序(对于用 C 编写的函数)¶ ↑
对于用 Ruby 编写的函数,RDoc 自动记录调用顺序。
对于用 C 编写的函数,RDoc 无法确定方法接受哪些参数,因此需要使用 RDoc 指令 {call-seq:
}记录这些参数。
对于单例方法,请使用以下形式
class_name.method_name(method_args) {|block_args| ... } -> return_type
示例
* call-seq: * Hash.new(default_value = nil) -> new_hash * Hash.new {|hash, key| ... } -> new_hash
对于实例方法,请使用以下形式(省略任何前缀,就像 RDoc
对 Ruby 编码方法所做的那样)
method_name(method_args) {|block_args| ... } -> return_type
例如,在 Array
中,请使用
* call-seq: * count -> integer * count(obj) -> integer * count {|element| ... } -> integer
* call-seq: * <=> other -> -1, 0, 1, or nil
参数
-
如果方法不接受参数,请省略括号。
-
如果方法接受可选参数
-
使用
=
(等号和周围空格)分隔每个参数名称及其默认值。 -
如果方法对省略的参数或显式参数具有相同行为,请使用带有可选参数的
call-seq
。例如,请使用respond_to?(symbol, include_all = false) -> true or false
-
如果对省略的参数或显式参数的行为不同,请使用带有单独行的
call-seq
。例如,在Enumerable
中,请使用* max -> element * max(n) -> array
-
块
-
如果方法不接受块,请省略块。
-
如果方法接受块,则
call-seq
应为{|args| ... }
,而不是{|args| block }
或{|args| code }
。
返回类型
-
如果方法可以返回多种不同的类型,请使用“或”分隔类型,必要时使用逗号。
-
如果方法可以返回多种类型,请使用
object
。 -
如果方法返回接收器,请使用
self
。 -
如果方法返回同一类的对象,仅当对象不是
self
时添加前缀new_
;示例:new_array
。
别名
-
从
call-seq
中省略别名,除非别名是运算符方法。如果在call-seq
中同时列出常规方法和运算符方法,请在详细信息和示例部分解释建议在何时使用常规方法以及建议在何时使用运算符方法。
概要¶ ↑
接下来是概要,它是对方法的作用以及您希望使用它的原因的简短描述。理想情况下,这是一句话,但对于更复杂的方法,可能需要一整段。
对于 Array#count
,概要是
Returns a count of specified elements.
这很好,因为它简短且具有描述性。避免在概要中记录太多内容,坚持为读者提供最重要的信息。
详细信息和示例¶ ↑
大多数非平凡的方法受益于示例,以及概要中未提供的信息。在详细信息和示例部分,您可以记录方法如何处理不同类型的参数,并提供有关正确用法的示例。在此部分中,重点关注如何正确使用该方法,而不是该方法如何处理不当的参数或特殊情况。
并非方法的每种行为都需要示例。如果记录的方法返回 self
,则无需提供示例来显示返回值与接收器相同。如果记录的方法返回 nil
,则无需提供示例来显示它返回 nil
。如果详细信息中提到对于某种参数类型,将返回一个空数组,则无需为此提供示例。
仅在示例为用户提供附加信息时添加示例,如果示例提供概要或详细信息中提供的信息,请不要添加示例。示例的目的是不证明详细信息中陈述的内容。
参数描述(如果需要)¶ ↑
对于需要参数的方法,如果在详细信息中没有明确提及或在示例中没有隐式显示,并且不明显,则可以提供对所支持的参数类型的详细信息。在讨论参数类型时,即使不太精确,也要使用简单的语言,例如“level 必须是整数”,而不是“level 必须是可以转换为 Integer 的对象”。绝大多数使用情况都将使用预期类型,而不是可以明确转换为预期类型的参数,记录差异并不重要。
对于采用块的方法,如果在详细信息中没有明确提及或在示例中没有隐式显示,并且不明显,则记录传递的参数类型可能很有用。
如果有多个参数或块参数,请使用 标记列表。
特殊情况和异常¶ ↑
对于方法的特殊情况,例如非典型用法,请简要提及行为,但不要提供任何示例。
仅记录非显而易见的引发异常。例如,如果您之前已声明参数类型必须是整数,则无需记录如果传递非整数,则会引发 TypeError
。除非是常见情况,例如 Hash#fetch
引发 KeyError
,否则不要提供引发异常的示例。
相关方法(可选)¶ ↑
在某些情况下,记录哪些方法与当前方法相关很有用。例如,Hash#[]
的文档可以提及 Hash#fetch
作为相关方法,而 Hash#merge
可以提及 Hash#merge!
作为相关方法。
-
考虑哪些方法可能与当前方法相关,如果您认为读者会受益,则在方法文档的末尾添加一行,以“相关:”开头(例如“相关:获取。”)。
-
不要列出超过三个相关方法。如果您认为超过三个方法相关,请列出您认为最重要的三个方法。
-
考虑添加
-
一个短语,建议相关方法如何与当前方法相似或不同。请参阅
Time#getutc
中的示例。 -
示例代码,说明相似性和差异性。请参阅
Time#ctime
、Time#inspect
、Time#to_s
中的示例。
-
接受多种参数类型的函数¶ ↑
对于接受多种参数类型的函数,在某些情况下,单独记录不同的参数类型可能很有用。最好为要讨论的每种情况使用一个单独的段落。