You want to create a set of API documentation for your application. You might want to go so far as to keep all your documentation in the same files as your source code.
Its good programming practice to preface each of your methods, classes, and modules with a comment that lets the reader know whats going on. Ruby rewards this behavior by making it easy to transform those comments into a set of HTML pages that document your code. This is similar to Javas JavaDoc, Pythons PyDoc, and Perls Pod.
Heres a simple example. Suppose your application contains only one file, sum.rb, which defines only one method:
def sum(*terms) terms.inject(0) { |sum, term| sum + term} end
To document this application, use Ruby comments to document the method, and also to document the file as a whole:
# Just a simple file that defines a sum method. # Takes any number of numeric terms and returns the sum. # sum(1, 2, 3) # => 6 # sum(1, -1, 10) # => 10 # sum(1.5, 0.2, 0.3, 1) # => 3.0 def sum(*terms) terms.inject(0) { |sum, term| sum + term} end
Change into the directory containing the sum.rb file, and run the rdoc command.
$ rdoc sum.rb: . Generating HTML… Files: 1 Classes: 0 Modules: 0 Methods: 1 Elapsed: 0.101s
The rdoc command creates a doc/ subdirectory beneath the current directory. It parses every Ruby file it can find in or below the current directory, and generates HTML files from the Ruby code and the comments that document it.
The index.html file in the doc/ subdirectory is a frameset that lets users navigate the files of your application. Since the example only uses one file (sum.rb), the most interesting thing about its generated documentation is what RDoc has done with the comments (Figure 17-1).
RDoc parses a set of Ruby files, cross-references them, and generates a web site that captures the class and module structure, and the comments you wrote while you were coding.
Generated RDoc makes for a useful reference to your classes and methods, but its not a substitute for handwritten examples or tutorials. Of course, RDoc comments can contain handwritten examples or tutorials. This will help your users and also help you keep your documentation together with your code.
Notice that when I wrote examples for the sum method, I indented them a little from the text above them:
# Takes any number of numeric terms and returns the sum. # sum(1, 2, 3) # => 6
RDoc picked up on this extra indentation and displayed my examples as Ruby code, in a fixed-width font. This is one of many RDoc conventions for improving the looks of the rendered HTML. As with wiki markup, the goal of the RDoc conventions is to allow text to render nicely as HTML while being easy to read and edit as plain text (Figure 17-2).
# =A whirlwind tour of SimpleMarkup # # ==You can mark up text # # * *Bold* a single word or a section # * _Emphasize_ a single word or a section # * Use a fixed-width font for a section or a +word+ # * URLs are automatically linked: # # ==Or create lists # # Types of lists: # * Unordered lists (like this one, and the one above) # * Ordered lists # 1. Line # 2. Square # 3. Cube # * Definition-style labelled lists (useful for argument lists) # [pos] Coordinates of the center of the circle ([x, y]) # [radius] Radius of the circle, in pixels # * Table-style labelled lists # Author:: Sophie Aurus # Homepage::
There are also several special RDoc directives that go into comments on the same line as a method, class, or module definition. The most common is :nodoc:, which is used if you want to hide something from RDoc. You can and should put an RDoc-style comment even on a :nodoc: method or class, so that people reading your Ruby code will know what it does.
# This class and its contents are hidden from RDoc; heres what it does: # … # class HiddenClass # :nodoc: # … end
Private methods don show up in RDoc generated documentationthat would usually just mean clutter. If you want one particular private method to show up in the documentation (probably for the benefit of people subclassing your class), use the :doc: directive; its the opposite of the :nodoc: directive: [1]
[1] If you want all private methods to show up in the documentation, pass the --all argument to the rdoc command. The rdoc command supports many command-line arguments, giving you control over the rules for generating the documentation and the layout of the results.
class MyClass private def hidden_method end def visible_method # :doc: end end
If a comment mentions another class, method, or source file, RDoc will try to locate and turn it into a hyperlinked cross-reference. To indicate that a method name is a method name and not just a random word, prefix it with a hash symbol or use its fully qualified name (MyClass.class_method or MyClass#instance_method:
# The SimplePolynomial class represents polynomials in one variable # and can perform most common operations on them. # # See especially #solve and #derivative. For multivariate polynomials, # see MultivariatePolynomial (especially # MultivariatePolynomial#simplify, which may return a # SimplePolynomial), and much of calculus.rb.
The Ruby gem installation process generates a set of RDoc files for every gem it installs. If you package your software as a gem, anyone who installs it will automatically get the RDoc files as well.
You can also create RDoc files programatically from a Ruby program, by creating and scripting RDoc objects. The rdoc command itself is nothing more than Ruby code such as the following, along with some error handling:
#!/usr/bin/ruby # rdoc.rb require doc/rdoc RDoc::RDoc.new.document(ARG