summaryrefslogtreecommitdiff
path: root/doc/method_documentation.rdoc
blob: 0432216868c81667b838d7e3cc6d687668b2239f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
= Method Documentation Guide

This guide discusses recommendations for documenting methods for Ruby core
classes and classes in the standard library.

== Goal

The goal when documenting a method is to impart the most important
information about the method in the least amount of time.  A reader
of the method documentation should be able to quickly understand
the purpose of the method and how to use it.  Providing too little
information about the method is not good, but providing unimportant
information or unnecessary examples is not good either.  Use your
judgment about what the user of the method needs to know to use the
method correctly.

== General Structure

The general structure of the method documentation should be:

* call-seq (for methods written in C)
* Synopsis (Short Description)
* Details and Examples
* Argument Description (if necessary)
* Corner Cases and Exceptions
* Aliases
* Related Methods (optional)

== call-seq (for methods written in C)

For methods written in C, RDoc cannot determine what arguments
the method accepts, so those need to be documented using a
<tt>call-seq</tt>.  Here's an example <tt>call-seq</tt>:

  *  call-seq:
  *    array.count -> integer
  *    array.count(obj) -> integer
  *    array.count {|element| ... } -> integer

When creating the <tt>call-seq</tt>, use the form

  receiver_type.method_name(arguments) {|block_arguments|} -> return_type

Omit the parentheses for cases where the method does not accept arguments,
and omit the block for cases where a block is not accepted.

In the cases where method can return multiple different types, separate the
types with "or".  If the method can return any type, use "object".  If the
method returns the receiver, use "self".

In cases where the method accepts optional arguments, use a <tt>call-seq</tt>
with an optional argument if the method has the same behavior when an argument
is omitted as when the argument is passed with the default value.  For example,
use:

  *     obj.respond_to?(symbol, include_all=false) -> true or false

Instead of:

  *     obj.respond_to?(symbol) -> true or false
  *     obj.respond_to?(symbol, include_all) -> true or false

However, as shown above for <tt>Array#count</tt>, use separate lines if the
behavior is different if the argument is omitted.

Omit aliases from the call-seq.

== Synopsis

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 <tt>Array#count</tt>, the synopsis is:

  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.

== Details and Examples

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 +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.

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.

== Argument Description (if necessary)

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 an RDoc
definition list:

argument_name1 :: type and description
argument_name2 :: type and description

== Corner Cases and Exceptions

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 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 KeyError.

== Aliases

Mention aliases in the form "Array#find_index is an alias for Array#index."

== Related Methods (optional)

In some cases, it is useful to document which methods are related to
the current method.  For example, documentation for Hash#[] might
mention Hash#fetch as a related method, and Hash#merge might mention
#merge! as a related method.  Consider which methods may be related
to the current method, and if you think the reader would benefit 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,
pick the three you think are most important and list those three.

== Methods Accepting Multiple Argument Types

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.

== Use of English

Readers of this documentation may not be native speakers of English.
Documentation should be written with this in mind.

Use short sentences and group them into paragraphs that cover a single
topic.  Avoid complex verb tenses, excessive comma-separated phrases,
and idioms.

When writing documentation, define unusual or critical concepts in
simple language.  Provide links to authoritative sources, or add a
general description to the top-level documentation for the class or
module.

== Formatting

Extraneous formatting such as headings and horizontal lines should be
avoided in general.  It is best to keep the formatting as simple as
possible.  Only use headings and other formatting for the most complex
cases where the method documentation is very long due to the complexity
of the method.

Methods are documented using RDoc syntax.  See the
{RDoc Markup Reference}[https://docs.ruby-lang.org/en/master/RDoc/Markup.html#class-RDoc::Markup-label-RDoc+Markup+Reference]
for more information on formatting with RDoc syntax.