summaryrefslogtreecommitdiff
path: root/doc/contributing/documentation_guide.md
blob: 59953d0d5247bac6c31cb4129aa77d3dd98bcbb5 (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# 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](rdoc-ref:RDoc::Markup).

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:

```sh
make html
```

If you don't have a build directory, follow the [quick start
guide](building_ruby.md#label-Quick+start+guide) up to step 4.

Then you can preview your changes by opening
`{build folder}/.ext/html/index.html` file in your browser.

## 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](rdoc-ref:RDoc::MarkupReference@Headings).
- Refer to authoritative and relevant sources using
  [links](rdoc-ref:RDoc::MarkupReference@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](rdoc-ref:RDoc::MarkupReference@Lists).
    - Idioms and culture-specific references.
    - Overuse of headings.
    - Using US-ASCII-incompatible characters in C source files;
      see [Characters](#label-Characters) 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 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 file `foo.c`),
  create file `doc/foo.rdoc`, declare `class 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 file `bar.c`,
  create file `doc/bar.rdoc`, declare `module 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:

    ```
    /*
     *  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](rdoc-ref:RDoc::Markup@RDoc+Markup+Reference).

### Output from `irb`

For code examples, consider using interactive Ruby,
[irb](https://ruby-doc.org/stdlib/libdoc/irb/rdoc/IRB.html).

For a code example that includes `irb` output,
consider aligning `# => ...` in successive lines.
Alignment may sometimes aid readability:

```ruby
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](rdoc-ref:RDoc::MarkupReference@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](rdoc-ref:RDoc::MarkupReference@Bold)
as pseudo-headings.

### Blank Lines

A blank line begins a new paragraph.

A [code block](rdoc-ref:RDoc::MarkupReference@Code+Blocks)
or [list](rdoc-ref:RDoc::MarkupReference@Lists)
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:
  <tt>::bar</tt>, <tt>#baz</tt>.
- Otherwise, include the class or module name
  and use a dot for a singleton method,
  or a hash mark for an instance method:
  <tt>Foo.bar</tt>, <tt>Foo#baz</tt>.

### Embedded Code and Commands

Code or commands embedded in running text (i.e., not in a code block)
should marked up as
[monofont](rdoc-ref:RDoc::MarkupReference@Monofont).

Code that is a simple string should include the quote marks.

### Auto-Linking

In general, \RDoc's auto-linking should not be suppressed.
For example, we should write `Array`, not `\Array`.

However, suppress when the word in question:

- Does not refer to a Ruby entity
  (e.g., some uses of _Class_ or _English_).
- Refers to the current document
  (e.g., _Array_ in the documentation for class `Array`);
  in that case, the word should be forced to
  [monofont](rdoc-ref:RDoc::MarkupReference@Monofont).

Most often, the name of a class, module, or method
will be auto-linked:

- Array.
- Enumerable.
- File.new
- File#read.

If not, or if you suppress autolinking, consider forcing
[monofont](rdoc-ref:RDoc::MarkupReference@Monofont).

### 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}[rdoc-ref:RDoc::MarkupReference@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 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.

### Variable Names

The name of a variable (as specified in its call-seq) should be marked up as
[monofont](rdoc-ref:RDoc::MarkupReference@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
(<tt><table></tt>, etc.).

Alternatives:

- A {verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks],
  using spaces and punctuation to format the text;
  note that {text markup}[rdoc-ref:RDoc::MarkupReference@Text+Markup]
  will not be honored:

    - Example {source}[https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/file.c#L6570-L6596].
    - Corresponding {output}[rdoc-ref:File@Read-2FWrite+Mode].

- (Markdown format only): A {Github Flavored Markdown (GFM) table}[https://github.github.com/gfm/#tables-extension-],
  using special formatting for the text:

    - Example {source}[https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/doc/contributing/glossary.md?plain=1].
    - Corresponding {output}[https://docs.ruby-lang.org/en/master/contributing/glossary_md.html].

## Documenting Classes and Modules

The general structure of the class or module documentation should be:

- Synopsis
- Common uses, with examples
- "What's Here" summary (optional)

### Synopsis

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.

### Common Uses

Show common uses of the class or module.
Depending on the class or module, this section may vary greatly
in both length and complexity.

### What's Here Summary

The documentation for a class or module may include a "What's Here" section.

Guidelines:

- The section title is `What's Here`.
- Consider listing the parent class and any included modules; consider
  [links](rdoc-ref:RDoc::MarkupReference@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:

    - 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](rdoc-ref:RDoc::MarkupReference@Links).

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

## Documenting Methods

### General Structure

The general structure of the method documentation should be:

- Calling sequence (for methods written in C).
- Synopsis (short description).
- Details and examples.
- Argument description (if necessary).
- Corner cases and exceptions.
- Related methods (optional).

### Calling Sequence (for methods written in C)

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
[`call-seq:`](rdoc-ref:RDoc::MarkupReference@Directives+for+Method+Documentation).

For a singleton method, use the form:

```
class_name.method_name(method_args) {|block_args| ... } -> return_type
```

Example:

```
*  call-seq:
*    Hash.new(default_value = nil) -> new_hash
*    Hash.new {|hash, key| ... } -> new_hash
```

For an instance method, use the form
(omitting any prefix, just as RDoc does for a Ruby-coded method):

```
method_name(method_args) {|block_args| ... } -> return_type
```
For example, in Array, use:

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

```
* call-seq:
*    <=> other -> -1, 0, 1, or nil
```

Arguments:

- If the method does not accept arguments, omit the parentheses.
- If the method accepts optional arguments:

    - 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:

        ```
        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:

        ```
        *    max    -> element
        *    max(n) -> array
        ```

Block:

- If the method does not accept a block, omit the block.
- If the method accepts a block, the `call-seq` should have `{|args| ... }`,
  not `{|args| block }` or `{|args| code }`.

Return types:

- If the method can return multiple different types,
  separate the types with "or" and, if necessary, commas.
- If the method can return multiple types, use +object+.
- If the method returns the receiver, use +self+.
- If the method returns an object of the same class,
  prefix `new_` if an only if the object is not  +self+;
  example: `new_array`.

Aliases:

- Omit aliases from the `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

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 `Array#count`, 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 a
[labeled list](rdoc-ref:RDoc::MarkupReference@Labeled+Lists).

### 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 a `KeyError`.

### 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
`Hash#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,
  list the three you think are most important.
- Consider adding:

    - A phrase suggesting how the related 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

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.