Documentation Guide
This guide discusses recommendations for documenting classes, modules, and methods in the Ruby core and in the Ruby standard library.
Generating documentation
Most Ruby documentation lives in the source files, and is written in RDoc format (described in the RDoc Markup Reference).
Some pages live under the doc folder and can be written in either
.rdoc or .md format, determined by the file extension.
To generate the output of documentation changes in HTML in the
{build folder}/.ext/html directory, run the following inside your
build directory:
make html
Or, to start a live-reloading server that automatically refreshes the browser when you edit source files:
make html-server
Then visit http://localhost:4000 in your browser.
To use a different port: make html-server RDOC_SERVER_PORT=8080.
If you don't have a build directory, follow the quick start guide up to step 4.
Goal
The goal of Ruby documentation is to impart the most important and relevant information in the shortest time. The reader should be able to quickly understand the usefulness of the subject code and how to use it.
Providing too little information is bad, but providing unimportant information or unnecessary examples is not good either. Use your judgment about what the user needs to know.
General Guidelines
- Keep in mind that the reader may not be fluent in English.
- Write short declarative or imperative sentences.
- Group sentences into (ideally short) paragraphs, each covering a single topic.
- Organize material with headings.
- Refer to authoritative and relevant sources using links.
- Use simple verb tenses: simple present, simple past, simple future.
- Use simple sentence structure, not compound or complex structure.
- Avoid:
- Excessive comma-separated phrases; consider a [list][lists]. - Idioms and culture-specific references. - Overuse of headings. - Using US-ASCII-incompatible characters in C source files; see <a href='#Characters'>Characters</a> below.
Characters
Use only US-ASCII-compatible characters in a C source file. (If you use other characters, the Ruby CI will gently let you know.)
If you want to put ASCII-incompatible characters into the documentation
for a C-coded class, module, or method, there are workarounds
involving new files doc/*.rdoc:
-
For class
Foo(defined in filefoo.c), create filedoc/foo.rdoc, declareclass Foo; end, and place the class documentation above that declaration:```ruby # Documentation for class Foo goes here. class Foo; end ``` -
Similarly, for module
Bar(defined in filebar.c), create filedoc/bar.rdoc, declaremodule Bar; end, and place the module documentation above that declaration:```ruby # Documentation for module Bar goes here. module Bar; end ``` -
For a method, things are different. Documenting a method as above disables the "click to toggle source" feature in the rendered documentation.
Therefore it's best to use file inclusion: - Retain the `call-seq` in the C code. - Use file inclusion (`:include:`) to include text from an .rdoc file. Example: ```c /* * call-seq: * each_byte {|byte| ... } -> self * each_byte -> enumerator * * :include: doc/string/each_byte.rdoc * */ ```
RDoc
Ruby is documented using RDoc. For information on RDoc syntax and features, see the RDoc Markup Reference.
Output from irb
For code examples, consider using interactive Ruby, irb.
For a code example that includes irb output,
consider aligning # => ... in successive lines.
Alignment may sometimes aid readability:
a = [1, 2, 3] #=> [1, 2, 3]
a.shuffle! #=> [2, 3, 1]
a #=> [2, 3, 1]
Headings
Organize a long discussion for a class or module with headings.
Do not use formal headings in the documentation for a method or constant.
In the rare case where heading-like structures are needed within the documentation for a method or constant, use bold text as pseudo-headings.
Blank Lines
A blank line begins a new paragraph.
A code block
or list should be preceded by and followed by a blank line.
This is unnecessary for the HTML output, but helps in the ri output.
Method Names
For a method name in text:
- For a method in the current class or module,
use a double-colon for a singleton method,
or a hash mark for an instance method:
.bar,#baz. - Otherwise, include the class or module name
and use a dot for a singleton method,
or a hash mark for an instance method:
Foo.bar,Foo#baz.
Embedded Code and Commands
Code or commands embedded in running text (i.e., not in a code block) should marked up as monofont.
Code that is a simple string should include the quote marks.
Auto-Linking
Most often, the name of a class, module, or method is auto-linked:
- Float.
- Enumerable.
- {File.new}
- {File#read}.
renders as:
- Float.
- Enumerable.
File.newFile#read.
In general, RDoc's auto-linking should not be suppressed. For example, we should write just plain Float (which is auto-linked):
Returns a Float.
which renders as:
Returns a Float.
However, do suppress auto-linking when the word in question does not refer to a Ruby entity (e.g., some uses of Class or English):
Class variables can be tricky.
renders as:
Class variables can be tricky.
Also, do suppress auto-linking when the word in question refers to the current document (e.g., Float in the documentation for class Float).
In this case you may consider forcing the name to monofont, which suppresses auto-linking, and also emphasizes that the word is a class name:
A {Float} object represents ....
renders as:
A
Floatobject represents ....
For a very few, very often-discussed classes, you might consider avoiding the capitalized class name altogether. For example, for some mentions of arrays, you might write simply the lowercase array.
Instead of:
For an empty Array, ....
which renders as:
For an empty Array, ....
you might write:
For an empty array, ....
which renders as:
For an empty array, ....
This more casual usage avoids both auto-linking and distracting font changes, and is unlikely to cause confusion.
This principle may be usefully applied, in particular, for:
- An array.
- An integer.
- A hash.
- A string.
However, it should be applied only when referring to an instance of the class, and never when referring to the class itself.
Explicit Links
When writing an explicit link, follow these guidelines.
rdoc-ref Scheme
Use the rdoc-ref scheme for:
- A link in core documentation to other core documentation.
- A link in core documentation to documentation in a standard library package.
- A link in a standard library package to other documentation in that same standard library package.
See section "rdoc-ref Scheme" in links.
URL-Based Link
Use a full URL-based link for:
- A link in standard library documentation to documentation in the core.
- A link in standard library documentation to documentation in a different standard library package.
Doing so ensures that the link will be valid even when the package documentation is built independently (separately from the core documentation).
The link should lead to a target in https://docs.ruby-lang.org/en/master/.
Also use a full URL-based link for a link to an off-site document.
Fragments
In general, a link that includes a fragment must cite the exact identifier on the target page; otherwise, the browser finds no suitable identifier, and does not scroll to the desired part of the page.
However, certain pages on github.com and github.io
support "fuzzy" identifier matching, so that URL
https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#-why-are-rubys-floats-imprecise,
(whose fragment is -why-are-rubys-floats-imprecise)
scrolls to heading "Why are ruby’s floats imprecise?"
even though the identifier there actually is the longer
#user-content--why-are-rubys-floats-imprecise.
Ruby documentation should avoid using these shortened fragments, for two reasons:
- The GitHub pages that do this implement it using Javascript; if the user's browser has Javascript disabled (which some employers actually require), the shortened fragment is ineffective and the desired scrolling does not occur.
- A program that checks links in Ruby documentation will find no suitable identifier, and therefore will report the fragment as not found.
Variable Names
The name of a variable (as specified in its call-seq) should be marked up as monofont.
Also, use monofont text for the name of a transient variable
(i.e., one defined and used only in the discussion, such as n).
HTML Tags
In general, avoid using HTML tags (even in formats where it's allowed)
because ri (the Ruby Interactive reference tool)
may not render them properly.
Tables
In particular, avoid building tables with HTML tags
( Alternatives: A verbatim text block,
using spaces and punctuation to format the text;
note that text markup will not be honored: (Markdown format only): A Github Flavored Markdown (GFM) table,
using special formatting for the text: For symbols and strings in documentation examples: The general structure of the class or module documentation should be: The synopsis is a short description of what the class or module does
and why the reader might want to use it.
Avoid details in the synopsis. Show common uses of the class or module.
Depending on the class or module, this section may vary greatly
in both length and complexity. The documentation for a class or module may include a "What's Here" section. Guidelines: The section title is Consider listing the parent class and any included modules; consider
links to their "What's Here" sections if those exist. All methods mentioned in the left-pane table of contents
should be listed (including any methods extended from another class). Attributes (which are not included in the TOC) may also be listed. Display methods as items in one or more bullet lists: If there are numerous entries, consider grouping them into subsections with headings. If there are more than a few such subsections,
consider adding a table of contents just below the main section title. The general structure of the method documentation should be: For methods written in Ruby, RDoc documents the calling sequence automatically. For methods written in C, RDoc cannot determine what arguments
the method accepts, so those need to be documented using RDoc directive
For a singleton method, use the form: Example: For an instance method, use the form
(omitting any prefix, just as RDoc does for a Ruby-coded method): For example, in Array, use: For a binary-operator style method (e.g., Arguments: If the method does not accept arguments, omit the parentheses. If the method accepts optional arguments: Block: If the method does not accept a block, omit the block. If the method accepts a block, the If the method accepts a block, but returns an Enumerator when the block is omitted,
the Return types: Aliases: The synopsis comes next, and is a short description of what the
method does and why you would want to use it. Ideally, this
is a single sentence, but for more complex methods it may require
an entire paragraph. For Returns a count of specified elements. This is great as it is short and descriptive. Avoid documenting
too much in the synopsis, stick to the most important information
for the benefit of the reader. For a method whose documentation is lengthy,
consider adding an "in-brief" passage,
showing examples that summarize the method's uses. The passage may answer some users' questions
(without their having to read long documentation);
see Most non-trivial methods benefit from examples, as well as details
beyond what is given in the synopsis. In the details and examples
section, you can document how the method handles different types
of arguments, and provides examples on proper usage. In this
section, focus on how to use the method properly, not on how the
method handles improper arguments or corner cases. Not every behavior of a method requires an example. If the method
is documented to return Only add an example if it provides the user additional information,
do not add an example if it provides the same information given
in the synopsis or details. The purpose of examples is not to prove
what the details are stating. Many methods that can take an optional block call the block if it is given,
but return a new Enumerator if the block is not given;
in that case, do not provide an example,
but do state the fact (with the auto-linking uppercase Enumerator): For methods that require arguments, if not obvious and not explicitly
mentioned in the details or implicitly shown in the examples, you can
provide details about the types of arguments supported. When discussing
the types of arguments, use simple language even if less-precise, such
as "level must be an integer", not "level must be an Integer-convertible
object". The vast majority of use will be with the expected type, not an
argument that is explicitly convertible to the expected type, and
documenting the difference is not important. For methods that take blocks, it can be useful to document the type of
argument passed if it is not obvious, not explicitly mentioned in the
details, and not implicitly shown in the examples. If there is more than one argument or block argument, use a
labeled list. For corner cases of methods, such as atypical usage, briefly mention
the behavior, but do not provide any examples. Only document exceptions raised if they are not obvious. For example,
if you have stated earlier than an argument type must be an integer,
you do not need to document that a In some cases, it is useful to document which methods are related to
the current method. For example, documentation for Consider which methods may be related
to the current method, and if you think the reader would benefit from it,
at the end of the method documentation, add a line starting with
"Related: " (e.g. "Related: #fetch."). Don't list more than three related methods.
If you think more than three methods are related,
list the three you think are most important. Consider adding: For methods that accept multiple argument types, in some cases it can
be useful to document the different argument types separately. It's
best to use a separate paragraph for each case you are discussing., etc.).
- Example <a href='https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/file.c#source'>source</a>.
- Corresponding <a href='File#output'>output</a>.- Example <a href='https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/doc/contributing/glossary.html?plain=1'>source</a>.
- Corresponding <a href='https://docs.ruby-lang.org/en/master/contributing/glossary_md.html'>output</a>.Languages in Examples
String#capitalize.Documenting Classes and Modules
Synopsis
Common Uses
What's Here Summary
What's Here.- Begin each item with the method name, followed by a colon
and a short description.
- If the method has aliases, mention them in parentheses before the colon
(and do not list the aliases separately).
- Check the rendered documentation to determine whether RDoc has recognized
the method and linked to it; if not, manually insert a
[link][links].Documenting Methods
General Structure
Calling Sequence (for methods written in C)
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
method_name(method_args) {|block_args| ... } -> return_type
* call-seq:
* count -> integer
* count(obj) -> integer
* count {|element| ... } -> integer
* call-seq:
* <=> other -> -1, 0, 1, or nil
Array#&),
cite self in the call-seq (not, e.g., array or receiver):* call-seq:
* self & other_array -> new_array
- Separate each argument name and its default value with ` = `
(equal-sign with surrounding spaces).
- If the method has the same behavior with either an omitted
or an explicit argument, use a `call-seq` with optional arguments.
For example, use:
```rdoc
* call-seq:
* respond_to?(symbol, include_all = false) -> true or false
```
- If the behavior is different with an omitted or an explicit argument,
use a `call-seq` with separate lines.
For example, in Enumerable, use:
```rdoc
* call-seq:
* max -> element
* max(n) -> array
```
call-seq should have {|args| ... },
not {|args| block } or {|args| code }.call-seq should show both forms:```rdoc
* call-seq:
* array.select {|element| ... } -> new_array
* array.select -> new_enumerator
```
object.self.new_ if and only if the object is not self;
example: new_array.
call-seq, unless the alias is an
operator method. If listing both a regular method and an
operator method in the call-seq, explain in the details and
examples section when it is recommended to use the regular method
and when it is recommended to use the operator method.Synopsis
Array#count, the synopsis is:
In-Brief Examples
Array#[] and Array#[]=.Details and Examples
self, you don't need to provide an example
showing the return value is the same as the receiver. If the method
is documented to return nil, you don't need to provide an example
showing that it returns nil. If the details mention that for a
certain argument type, an empty array is returned, you don't need
to provide an example for that.* With no block given, returns a new Enumerator.
Argument Description (if necessary)
Corner Cases and Exceptions
TypeError is raised if a non-integer
is passed. Do not provide examples of exceptions being raised unless
that is a common case, such as Hash#fetch raising a KeyError.Related Methods (optional)
Hash#[] might
mention Hash#fetch as a related method, and Hash#merge might mention
Hash#merge! as a related method.
- A phrase suggesting how the method is similar to,
or different from, the current method.
See an example at Time#getutc.
- Example code that illustrates the similarities and differences.
See examples at Time#ctime, Time#inspect, Time#to_s.Methods Accepting Multiple Argument Types