How I use YARD for Ruby

Sep 24, 2023

Ruby offers several code documentation specifications like RDoc, YARD, and TomDoc. Personally, I prefer YARD for its flexibility and rich feature set.

Getting Started with YARD

You can document your Ruby code using YARD by following a specific syntax. For example:

class Person
  # Greets a person
  #
  # @param [String] name the name of the person
  #
  # @return [String] the greeting
  def greet(name)
    "Hello #{name}"
  end
end

Installation and Usage

Install the YARD gem using:

gem install yard

To generate documentation, run:

yard doc person.rb

This generates a documentation site in the doc directory. You can preview it locally using:

yard server

Since the documentation consists of static HTML files, you can host it on any web server.

YARD Cheatsheet

I created a cheatsheet of all YARD tags:

# Represents a generic document in a document management system.
# @abstract
# @author John Doe
# @since 1.0.0
# @deprecated Use NewDocument instead.
class Document
  # @!attribute [r] title
  #   @return [String]
  attr_reader :title

  # @!attribute [w] description
  #   @return [String]
  attr_writer :description

  # @!attribute [rw] sections
  #   @api private
  #   @return [Array<Section>]
  attr_accessor :sections

  # Initializes a new Document instance.
  # @note This method should be called with care.
  #
  # @param [String] title the title of the document
  # @param [String] description the description of the document
  # @param [Hash] options additional configuration options
  # @option options [Boolean] :editable whether the document can be edited
  # @yieldparam [String] content The content of the document.
  # @yieldreturn [String] Returns a modified content.
  #
  # @raise [ArgumentError] if the title is nil
  #
  # @return [Document] a new Document instance
  def initialize(title, description, options = {})
    raise ArgumentError, "Title cannot be nil" unless title

    @title = title
    @description = description
    @editable = options.fetch(:editable, true)

    @content = yield(content) if block_given?
  end

  # Edits the document content.
  #
  # @overload edit(new_content)
  #   @param [String] new_content the new content for the document
  #   @return [Boolean] true if editing was successful, false otherwise
  #
  # @overload edit
  #   @yield Gives a block to process the current content.
  #   @yieldreturn [String] Returns the new content after processing.
  #   @return [Boolean] true if editing was successful, false otherwise
  #
  # @deprecated Use `modify` method instead.
  def edit(new_content = nil)
    if new_content
      @content = new_content
      true
    elsif block_given?
      @content = yield(@content)
      true
    else
      false
    end
  end

  # @todo Implement a proper save mechanism
  def save
    # Implementation pending
  end

  # Views the document
  #
  # @example Viewing the document title
  #   document.view_title #=> "Sample Document"
  #
  # @see #edit
  # @return [String] the title of the document
  def view_title
    @title
  end
end

It is available as a gist.

Custom Tags in YARD

YARD supports .yardopts for custom configuration, including custom tags. I use this to document Rails controller actions:

--tag url
--tag action

Example usage in a Rails controller:

class DocumentsController < ApplicationController

  # @url /documents
  # @action GET
  #
  # List all documents.
  #
  def index
    @documents = Document.all
  end

  # @url /documents/:id
  # @action GET
  #
  # Show a single document.
  #
  def show
    @document = Document.find(params[:id])
  end
end

Since params is not explicitly passed as an argument, you cannot use @param and @option to document them. One of the method that the YARD author suggests to document these methods is to use @overload tag.

  # @overload show(params)
  #   @param params [Hash]
  #   @option params [String] :id the id of the document
  def show
    @document = Document.find(params[:id])
  end

YARD in VSCode

VSCode has a YARD extension that provides auto-completion for YARD tags. You can generate documentation for a method by placing the cursor at the end of its definition and pressing Ctrl+Alt+Enter (or Option+Command+Enter on macOS).

For example, with the cursor anywhere on this line:

def foo(name, baz = false) # <- put cursor at any place of this line
end

The extension generates:

#
# <Description>
#
# @param [<Type>] name <description>
# @param [<Type>] baz <description>
#
# @return [<Type>] <description>
#
def foo(name, baz = false)
end

Conclusion

YARD is a powerful tool for documenting Ruby code. Whether you're working on a small project or a large codebase, using YARD improves code readability and maintainability.

Happy documenting!