文档指南¶ ↑
本指南讨论了在 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 会友好地提醒您。)
如果您想在 C 代码类、模块或方法的文档中添加与 ASCII 不兼容的字符,可以使用一些变通方法,例如创建新的文件 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)。
-
引用指向用户通常不处理的类或模块,包括以下内容
-
类。
-
方法。
-
模块。
-
大多数情况下,类、模块或方法的名称将被自动链接
如果没有,或者如果您抑制了自动链接,请考虑强制使用等宽字体。
显式链接¶ ↑
编写显式链接时,请遵循以下指南。
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) 表格
文档化类和模块¶ ↑
类或模块文档的一般结构应为
-
概要
-
常见用法,带示例
-
“这里有什么”摘要(可选)
概要¶ ↑
概要是对类或模块功能的简短描述,以及读者可能想要使用它的原因。在概要中避免细节。
常见用法¶ ↑
展示类或模块的常见用法。根据类或模块的不同,本节的长度和复杂度可能会有很大差异。
这里有什么摘要¶ ↑
类或模块的文档可能包含一个“这里有什么”部分。
指南
-
本节标题为
What's Here
。 -
考虑列出父类和任何包含的模块;考虑链接到它们的“What's Here”部分(如果存在)。
-
左侧窗格目录中提到的所有方法都应列出(包括从其他类扩展的任何方法)。
-
属性(未包含在 TOC 中)也可以列出。
-
将方法显示为一个或多个项目符号列表中的项目。
-
每个项目以方法名称开头,后跟冒号和简短描述。
-
如果方法有别名,请在冒号之前(并且不要单独列出别名)在括号中提及它们。
-
检查渲染后的文档以确定 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
的示例。如果详细信息提到对于特定参数类型,返回一个空数组,则不需要为此提供示例。
仅当示例为用户提供额外信息时才添加示例,如果示例提供与摘要或详细信息中相同的信息,则不要添加示例。示例的目的是不是为了证明详细信息的陈述。
参数描述(如有必要)¶ ↑
对于需要参数的方法,如果参数类型不明显且未在详细信息中明确提及或未在示例中隐式显示,则可以提供有关支持的参数类型的详细信息。在讨论参数类型时,即使不精确,也要使用简单的语言,例如“级别必须是整数”,而不是“级别必须是可转换为整数的对象”。绝大多数使用将使用预期类型,而不是显式可转换为预期类型的参数,记录这种差异并不重要。
对于接受块的方法,如果块参数类型不明显,未在详细信息中明确提及,也未在示例中隐式显示,记录传递的块参数类型可能会有用。
如果有多个参数或块参数,请使用 带标签的列表。
极端情况和异常¶ ↑
对于方法的极端情况,例如非典型用法,请简要提及行为,但不要提供任何示例。
仅当引发的异常不明显时才记录异常。例如,如果您之前已声明参数类型必须是整数,则无需记录如果传递非整数则会引发 TypeError
。除非这是一个常见情况,例如 Hash#fetch
引发 KeyError
,否则不要提供引发异常的示例。
相关方法(可选)¶ ↑
在某些情况下,记录哪些方法与当前方法相关很有用。例如,Hash#[]
的文档可能会提到 Hash#fetch
作为相关方法,而 Hash#merge
可能会提到 Hash#merge!
作为相关方法。
-
考虑哪些方法可能与当前方法相关,如果您认为读者会从中受益,请在方法文档的末尾添加以“相关:”开头的行(例如“相关:fetch。”)。
-
不要列出超过三个相关方法。如果您认为超过三个方法相关,请列出您认为最重要的三个方法。
-
考虑添加
-
一个短语,暗示相关方法与当前方法的相似之处或不同之处。请参阅
Time#getutc
中的示例。 -
说明异同的示例代码。请参阅
Time#ctime
、Time#inspect
、Time#to_s
中的示例。
-
接受多种参数类型的方法¶ ↑
对于接受多种参数类型的方法,在某些情况下,分别记录不同的参数类型可能会有用。最好为要讨论的每种情况使用单独的段落。