CrackedRuby logo

CrackedRuby

Documentation Best Practices

Overview

Ruby documentation encompasses multiple tools and conventions for creating maintainable technical documentation. The primary documentation systems include RDoc, which ships with Ruby and generates HTML documentation from source code comments, and YARD, which provides enhanced markup syntax and extensibility. Both systems parse specially formatted comments to extract API documentation, method signatures, parameter information, and usage examples.

RDoc uses a simple markup syntax embedded in Ruby comments. Comments beginning with ## or # immediately before method definitions become part of the generated documentation. RDoc recognizes standard formatting including *bold*, _italic_, and +code+ markup, along with structured elements like numbered lists and definition lists.

# Calculates compound interest for a given principal amount
# 
# * +principal+ - The initial amount (Float)
# * +rate+ - Annual interest rate as decimal (Float)  
# * +time+ - Investment period in years (Integer)
#
# Returns the total amount after compound interest calculation
def compound_interest(principal, rate, time)
  principal * (1 + rate) ** time
end

YARD extends RDoc capabilities with structured tags and improved type information. YARD tags like @param, @return, and @example provide semantic meaning to documentation elements. The tag-based approach enables better tooling integration and more precise API contracts.

# @param [String] name The user's full name
# @param [Integer] age The user's age in years  
# @return [Hash] User profile with normalized data
# @example Creating a user profile
#   create_profile("John Doe", 25)
#   #=> {name: "John Doe", age: 25, slug: "john-doe"}
def create_profile(name, age)
  {
    name: name,
    age: age, 
    slug: name.downcase.gsub(/\s+/, '-')
  }
end

Documentation generation integrates with standard Ruby workflows through rake tasks and command-line tools. The rdoc command processes Ruby files to produce HTML documentation trees, while yardoc provides similar functionality with additional customization options. Both tools support configuration files for consistent output across projects.

Basic Usage

Method documentation follows established patterns for parameter description, return value specification, and usage examples. Document public API methods completely while keeping private method documentation minimal. Focus documentation efforts on methods that external developers will call directly.

class DatabaseConnection
  # Establishes connection to database using provided configuration
  #
  # @param [Hash] config Database connection parameters
  # @option config [String] :host Database server hostname
  # @option config [Integer] :port Database server port (default: 5432)  
  # @option config [String] :database Database name
  # @return [DatabaseConnection] Connected database instance
  # @raise [ConnectionError] When connection parameters are invalid
  def self.connect(config)
    validate_config(config)
    new(config).tap(&:establish_connection)
  end

  # Executes SQL query with parameter binding
  #
  # @param [String] sql The SQL query with placeholder markers
  # @param [Array] params Parameters to bind to query placeholders
  # @return [Array<Hash>] Query results as array of row hashes
  def query(sql, params = [])
    prepare_statement(sql).execute(params)
  end
end

Class documentation describes the overall purpose, primary usage patterns, and key concepts. Include initialization requirements and basic workflow examples. Document class-level configuration options and their effects on instance behavior.

# Manages user authentication and session handling
#
# Provides secure authentication mechanisms including password hashing,
# session token generation, and multi-factor authentication support.
# Integrates with external identity providers through OAuth2 protocols.
#
# @example Basic authentication workflow
#   auth = AuthManager.new(config)
#   user = auth.authenticate(username, password) 
#   session = auth.create_session(user)
#   
# @example OAuth integration
#   auth.configure_oauth(:google, client_id: 'xxx', secret: 'yyy')
#   redirect_url = auth.oauth_authorization_url(:google)
class AuthManager
  def initialize(config)
    @config = config
    @providers = {}
  end
end

Module documentation explains the module's role in the system architecture and how including classes should use its functionality. Document module constants, class methods, and instance methods that modules contribute to including classes.

# Provides caching functionality for expensive operations
#
# Implements multiple caching strategies including memory, file system,
# and distributed caching. Automatically handles cache key generation,
# expiration policies, and cache invalidation patterns.
#
# @example Memory caching
#   class Calculator
#     include Cacheable
#     
#     cache_method :fibonacci, ttl: 3600
#     def fibonacci(n)
#       # expensive calculation
#     end
#   end
module Cacheable  
  def self.included(base)
    base.extend(ClassMethods)
  end
  
  module ClassMethods
    # Enables caching for the specified method
    # @param [Symbol] method_name Method to cache
    # @param [Hash] options Caching options
    # @option options [Integer] :ttl Time to live in seconds
    def cache_method(method_name, options = {})
      # implementation
    end
  end
end

Constant documentation explains the constant's purpose and acceptable values. Include examples of proper usage and any constraints on the constant's value. Document relationships between related constants within the same module or class.

class HTTPClient
  # Default timeout values for HTTP operations
  TIMEOUT_OPTIONS = {
    connect: 10,    # Connection establishment timeout (seconds)
    read: 30,       # Response read timeout (seconds)  
    write: 30       # Request write timeout (seconds)
  }.freeze
  
  # HTTP status codes requiring retry logic
  RETRYABLE_CODES = [408, 429, 502, 503, 504].freeze
  
  # Maximum number of retry attempts for failed requests
  MAX_RETRIES = 3
end

Advanced Usage

Custom YARD tags extend documentation capabilities for domain-specific requirements. Define tags using YARD's tag registration system to capture specialized metadata. Custom tags enable documentation of application-specific concepts like permissions, feature flags, or API versioning information.

# Register custom tags for API documentation
YARD::Tags::Library.define_tag("API Version", :api_version)
YARD::Tags::Library.define_tag("Required Permission", :requires_permission)
YARD::Tags::Library.define_tag("Feature Flag", :feature_flag)

class UserController
  # Updates user profile information
  #
  # @api_version 2.1
  # @requires_permission users:write
  # @feature_flag profile_editing_v2
  # @param [Integer] user_id Target user identifier
  # @param [Hash] attributes Profile attributes to update
  # @return [User] Updated user object
  def update_profile(user_id, attributes)
    # implementation
  end
end

Documentation templates standardize formatting across large codebases. YARD supports custom templates for consistent HTML output styling and content organization. Templates can include project-specific navigation, branding, and additional metadata sections.

# .yardopts configuration for custom templates
--template-path templates/
--template custom_template
--markup markdown
--charset utf-8
--output-dir doc/
--protected
--private
lib/**/*.rb

Macro definitions reduce documentation duplication for repetitive patterns. YARD macros expand into full documentation blocks, maintaining consistency while reducing maintenance overhead. Macros handle common patterns like attribute accessors, delegation methods, and configuration options.

# Define macro for documented attribute accessors
# @!macro [new] attr_documented
#   @!attribute [rw] $1  
#   @param [Object] value The $1 value
#   @return [Object] The current $1 value

class Configuration
  # @!macro attr_documented
  attr_accessor :timeout
  
  # @!macro attr_documented  
  attr_accessor :max_retries
  
  # @!macro attr_documented
  attr_accessor :base_url
end

Cross-reference linking connects related documentation elements automatically. YARD generates links between classes, methods, and modules based on naming conventions and explicit reference syntax. Maintain reference integrity across refactoring by using consistent naming patterns.

class PaymentProcessor
  # Processes payment using configured gateway
  #
  # Uses {GatewayConfig#primary_gateway} for payment routing.
  # Logs transaction details via {TransactionLogger#record}.
  # Raises {PaymentError} for processing failures.
  #
  # @param [Payment] payment Payment details
  # @see GatewayConfig#configure_gateway
  # @see TransactionLogger
  def process_payment(payment)
    gateway = GatewayConfig.primary_gateway
    TransactionLogger.record(payment, gateway)
    gateway.charge(payment.amount, payment.source)
  rescue Gateway::Error => e
    raise PaymentError, "Payment failed: #{e.message}"
  end
end

Conditional documentation addresses version-specific or environment-specific behavior. Document feature availability, deprecation timelines, and alternative implementations. Use YARD's conditional processing for version-specific documentation blocks.

class DatabaseAdapter  
  # Executes database query with optional connection pooling
  #
  # Connection pooling available in Ruby 2.7+ with fiber scheduler support.
  # Falls back to synchronous execution in earlier Ruby versions.
  #
  # @param [String] query SQL query string
  # @param [Hash] options Query execution options
  # @option options [Boolean] :async Use async execution (Ruby 2.7+)
  # @return [QueryResult] Query execution results
  def execute_query(query, options = {})
    if RUBY_VERSION >= '2.7.0' && options[:async]
      execute_async(query, options)
    else  
      execute_sync(query, options)
    end
  end
  
  private
  
  # @!visibility private
  def execute_async(query, options)
    # Fiber-based async implementation
  end
  
  # @!visibility private  
  def execute_sync(query, options)
    # Traditional synchronous implementation
  end
end

Testing Strategies

Documentation testing ensures accuracy and prevents documentation drift. Write tests that validate code examples execute correctly and produce expected outputs. Use tools like yard-doctest or custom test harnesses to verify documentation examples.

# spec/documentation_spec.rb
require 'yard'
require 'yard-doctest'

RSpec.describe 'Documentation Examples' do
  it 'validates all YARD examples' do
    YARD.parse(['lib/**/*.rb'])
    doctest = YardDoctest::DocTest.new
    
    expect(doctest.run).to be_truthy, 
      "Documentation examples failed validation"
  end
  
  it 'ensures API methods have examples' do
    missing_examples = []
    
    YARD::Registry.all(:method).each do |method|
      next if method.visibility != :public
      next if method.has_tag?(:example)
      
      missing_examples << method.path
    end
    
    expect(missing_examples).to be_empty,
      "Methods missing examples: #{missing_examples.join(', ')}"
  end
end

Test documentation coverage by analyzing parsed documentation trees. Measure coverage metrics including method documentation completeness, parameter documentation, and return value documentation. Establish coverage thresholds and monitor coverage trends over time.

class DocumentationCoverageAnalyzer
  def initialize(source_paths)
    @source_paths = source_paths
    YARD.parse(source_paths)
  end
  
  # Analyzes documentation coverage across the codebase
  #
  # @return [Hash] Coverage metrics including percentages and details
  def analyze_coverage
    methods = YARD::Registry.all(:method)
    public_methods = methods.select { |m| m.visibility == :public }
    
    documented_methods = public_methods.select { |m| documented?(m) }
    
    {
      total_methods: public_methods.size,
      documented_methods: documented_methods.size,
      coverage_percentage: (documented_methods.size.to_f / public_methods.size * 100).round(2),
      undocumented: public_methods - documented_methods
    }
  end
  
  private
  
  def documented?(method)
    return false unless method.docstring.present?
    return false unless method.tags(:param).size == method.parameters.size
    return false unless method.has_tag?(:return)
    true
  end
end

Documentation integration testing validates generated documentation against expected structure and content. Test navigation functionality, search capabilities, and cross-reference link integrity. Automated testing prevents broken documentation deployment.

# spec/integration/documentation_integration_spec.rb
require 'nokogiri'
require 'net/http'

RSpec.describe 'Generated Documentation' do
  before(:all) do
    system('bundle exec yardoc')
  end
  
  let(:doc_index) { File.read('doc/index.html') }
  let(:parsed_doc) { Nokogiri::HTML(doc_index) }
  
  it 'generates complete navigation structure' do
    nav_links = parsed_doc.css('#nav .item a')
    expect(nav_links.size).to be > 0
    
    nav_links.each do |link|
      href = link['href']
      expect(File.exist?("doc/#{href}")).to be true
    end
  end
  
  it 'includes all public classes in documentation' do
    class_names = YARD::Registry.all(:class).map(&:name).map(&:to_s)
    
    class_names.each do |class_name|
      expect(doc_index).to include(class_name)
    end
  end
  
  it 'validates cross-reference links' do
    cross_refs = parsed_doc.css('a.crossref')
    
    cross_refs.each do |link|
      href = link['href']
      next unless href.start_with?('#')
      
      target_id = href[1..]
      expect(parsed_doc.css("##{target_id}")).not_to be_empty
    end
  end
end

Mock documentation scenarios for complex dependencies or external services. Create documentation examples that don't require actual service connections or expensive operations. Use mock objects and stub data to demonstrate API usage patterns.

class PaymentGatewayDocumentation
  # Documents payment gateway integration patterns
  #
  # @example Processing a successful payment
  #   gateway = PaymentGateway.new(api_key: 'test_key')
  #   
  #   # Mock successful response for documentation
  #   allow(gateway).to receive(:charge).and_return(
  #     OpenStruct.new(
  #       success?: true,
  #       transaction_id: 'txn_123',
  #       amount: 2500
  #     )
  #   )
  #   
  #   result = gateway.charge(2500, payment_method)
  #   puts result.transaction_id  #=> "txn_123"
  #
  # @example Handling payment failures  
  #   allow(gateway).to receive(:charge).and_raise(
  #     PaymentGateway::DeclinedError.new('Insufficient funds')
  #   )
  #   
  #   begin
  #     gateway.charge(2500, payment_method)
  #   rescue PaymentGateway::DeclinedError => e
  #     puts "Payment declined: #{e.message}"
  #   end
  def document_payment_scenarios
    # Documentation examples only - no implementation needed
  end
end

Production Patterns

Continuous integration documentation ensures documentation stays current with code changes. Configure CI pipelines to generate and validate documentation automatically. Deploy updated documentation to staging environments for review before production publication.

# .github/workflows/documentation.yml configuration snippet
# 
# name: Documentation
# on: [push, pull_request]
# jobs:
#   generate:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v3
#       - uses: ruby/setup-ruby@v1
#         with:
#           bundler-cache: true
#       - name: Generate documentation
#         run: bundle exec yardoc
#       - name: Validate documentation
#         run: bundle exec rspec spec/documentation_spec.rb

class DocumentationDeployment
  # Manages documentation deployment pipeline
  #
  # Integrates with CI/CD systems to automate documentation generation
  # and deployment. Supports multiple environments and rollback capabilities.
  #
  # @param [Hash] config Deployment configuration
  # @option config [String] :target_environment Deployment target
  # @option config [String] :documentation_url Base URL for documentation
  def initialize(config)
    @config = config
    @generator = DocumentationGenerator.new
  end
  
  # Deploys documentation to specified environment
  #
  # @param [String] version Git commit or tag to deploy
  # @return [DeploymentResult] Deployment status and details
  def deploy(version)
    @generator.generate_for_version(version)
    upload_documentation
    update_search_index
    DeploymentResult.new(status: :success, url: documentation_url)
  rescue => e
    handle_deployment_failure(e)
  end
end

Documentation versioning maintains historical API documentation for multiple software versions. Implement version-specific documentation generation and hosting. Provide clear migration paths between API versions through comparative documentation.

class VersionedDocumentation
  VERSION_MAPPING = {
    'v1' => '1.0.0..1.9.9',
    'v2' => '2.0.0..2.9.9', 
    'v3' => '3.0.0..'
  }.freeze
  
  # Generates documentation for specific API version
  #
  # @param [String] version_tag Git tag or version identifier  
  # @param [Hash] options Generation options
  # @option options [Boolean] :include_deprecated Include deprecated methods
  # @return [String] Path to generated documentation
  def generate_version_docs(version_tag, options = {})
    checkout_version(version_tag)
    configure_yard_for_version(version_tag, options)
    
    output_path = "doc/versions/#{version_tag}"
    system("bundle exec yardoc --output-dir #{output_path}")
    
    generate_version_index(version_tag, output_path)
    output_path
  end
  
  private
  
  def configure_yard_for_version(version, options)
    config = base_yard_config
    config[:title] = "API Documentation v#{version}"
    config[:include_deprecated] = options.fetch(:include_deprecated, true)
    
    File.write('.yardopts', config.map { |k, v| "--#{k} #{v}" }.join("\n"))
  end
end

Documentation monitoring tracks usage patterns and identifies improvement opportunities. Monitor documentation site analytics, search queries, and user feedback. Use metrics to prioritize documentation updates and identify knowledge gaps.

class DocumentationMetrics
  # Analyzes documentation usage and effectiveness
  #
  # Tracks page views, search patterns, and user engagement metrics.
  # Identifies frequently accessed content and areas needing improvement.
  def initialize(analytics_client)
    @analytics = analytics_client
  end
  
  # Generates documentation usage report
  #
  # @param [Date] start_date Report period start
  # @param [Date] end_date Report period end  
  # @return [Hash] Usage metrics and recommendations
  def usage_report(start_date, end_date)
    page_views = @analytics.page_views(start_date, end_date)
    search_queries = @analytics.search_queries(start_date, end_date)
    
    {
      total_views: page_views.sum(&:views),
      top_pages: page_views.sort_by(&:views).reverse.first(10),
      common_searches: search_queries.group_by(&:query).transform_values(&:size),
      recommendations: generate_recommendations(page_views, search_queries)
    }
  end
  
  private
  
  def generate_recommendations(views, searches)
    low_traffic = views.select { |page| page.views < average_views(views) * 0.1 }
    failed_searches = searches.select { |search| search.results_count == 0 }
    
    {
      pages_needing_promotion: low_traffic.map(&:path),
      missing_content: failed_searches.map(&:query).uniq
    }
  end
end

Performance optimization for large documentation sites involves caching, compression, and efficient asset delivery. Implement static site generation with incremental builds. Use content delivery networks for global documentation distribution.

class DocumentationOptimizer
  # Optimizes documentation site performance
  #
  # Implements caching strategies, asset optimization, and incremental
  # generation for large documentation sites. Reduces build times and
  # improves user experience through performance optimizations.
  def initialize(site_config)
    @config = site_config
    @cache = DocumentationCache.new
  end
  
  # Performs incremental documentation build  
  #
  # Only rebuilds documentation for changed files, significantly reducing
  # build times for large projects with extensive documentation.
  #
  # @param [Array<String>] changed_files List of modified source files
  # @return [BuildResult] Build status and performance metrics
  def incremental_build(changed_files)
    start_time = Time.now
    
    affected_docs = determine_affected_documentation(changed_files)
    rebuild_documentation(affected_docs)
    optimize_assets
    
    BuildResult.new(
      duration: Time.now - start_time,
      files_processed: affected_docs.size,
      cache_hits: @cache.hit_count
    )
  end
  
  private
  
  def optimize_assets  
    compress_css_files
    optimize_javascript
    generate_responsive_images
  end
end

Common Pitfalls

Outdated documentation represents the most pervasive documentation problem. Documentation becomes stale when code changes without corresponding documentation updates. Establish processes that tie documentation updates to code changes through automated validation and review requirements.

# Common mistake: Documentation doesn't match implementation
class UserService
  # Validates user email format  
  # @param [String] email User email address
  # @return [Boolean] True if email is valid
  def validate_email(email)
    # Implementation changed but documentation didn't update
    result = EmailValidator.new(email).validate
    return result.success? && result.deliverable?  # Returns ValidatorResult, not Boolean
  end
end

# Better approach: Keep documentation synchronized
class UserService  
  # Validates user email format and deliverability
  # @param [String] email User email address  
  # @return [EmailValidationResult] Validation result with detailed status
  # @example Successful validation
  #   result = validate_email("user@example.com")  
  #   result.valid?        #=> true
  #   result.deliverable?  #=> true
  def validate_email(email)
    EmailValidator.new(email).validate
  end
end

Over-documentation clutters codebases with obvious or redundant information. Avoid documenting implementation details that change frequently or concepts that experienced developers understand implicitly. Focus documentation on public APIs, complex algorithms, and business logic.

# Over-documented: Obvious information adds no value
class Calculator
  # Adds two numbers together
  # @param [Integer] a The first number to add
  # @param [Integer] b The second number to add  
  # @return [Integer] The sum of a and b
  def add(a, b)
    a + b  # Returns the result of adding a and b
  end
  
  # Sets the value of x to the provided value
  # @param [Integer] value The value to set x to
  def x=(value)
    @x = value  # Assigns value to instance variable @x
  end
end

# Better: Document non-obvious behavior and edge cases  
class Calculator
  # Performs arbitrary precision decimal addition
  # Handles edge cases including infinity and NaN values
  # @param [Numeric] a First operand
  # @param [Numeric] b Second operand
  # @return [BigDecimal, Float] Sum with appropriate precision
  # @raise [ArgumentError] When operands cannot be coerced to numeric types
  def add(a, b)
    # Complex implementation with precision handling
  end
end

Inconsistent documentation styles create confusion and maintenance overhead. Establish style guides covering parameter description format, example structure, and cross-reference conventions. Use linting tools to enforce consistency automatically.

# Inconsistent documentation styles across methods
class ApiClient
  # Gets user data
  # userId: the user ID
  # Returns: user object
  def get_user(userId)
  end
  
  # @param [String] user_id The unique identifier for the user
  # @return [Hash] User profile information including name, email, preferences
  # @raise [NotFoundError] When user_id doesn't exist
  # @example
  #   client.fetch_user("123")  
  def fetch_user(user_id)
  end
end

# Consistent documentation following established patterns
class ApiClient
  # Retrieves user profile information
  # @param [String] user_id Unique user identifier
  # @return [Hash] User profile data
  # @raise [NotFoundError] When user doesn't exist
  def get_user(user_id)
  end
  
  # Retrieves detailed user information including preferences
  # @param [String] user_id Unique user identifier  
  # @return [Hash] Complete user profile with preferences
  # @raise [NotFoundError] When user doesn't exist
  def fetch_user(user_id)
  end
end

Missing error documentation leaves developers unprepared for exception handling. Document all exceptions that methods can raise, including inherited exceptions and exceptions from dependencies. Provide guidance on appropriate error handling strategies.

# Missing error documentation creates surprises
class DatabaseQuery
  # Executes SQL query against database
  # @param [String] sql Query to execute
  # @return [Array<Hash>] Query results
  def execute(sql)
    connection.query(sql)  # Can raise multiple exception types
  end
end

# Complete error documentation prevents surprises
class DatabaseQuery
  # Executes SQL query against database connection
  # @param [String] sql Valid SQL query string
  # @return [Array<Hash>] Query result rows as hash objects
  # @raise [ConnectionError] When database connection is unavailable
  # @raise [QueryError] When SQL syntax is invalid
  # @raise [TimeoutError] When query exceeds configured timeout
  # @raise [PermissionError] When user lacks required database privileges
  # @example Handling query errors
  #   begin
  #     results = query.execute("SELECT * FROM users")
  #   rescue QueryError => e
  #     logger.error "SQL error: #{e.message}"
  #     return []
  #   end
  def execute(sql)
    connection.query(sql)
  end
end

Documentation that assumes too much knowledge excludes potential users. Provide sufficient context for developers who may be unfamiliar with domain concepts or implementation patterns. Link to external resources for background information when appropriate.

# Assumes too much domain knowledge
class MLModelTrainer  
  # Trains model using backpropagation with SGD optimizer
  # @param [Array] features Feature vectors  
  # @param [Array] labels Target classifications
  # @return [TrainedModel] Optimized model weights
  def train(features, labels)
    # Assumes reader knows backpropagation, SGD, feature vectors
  end
end

# Provides sufficient context for broader audience
class MLModelTrainer
  # Trains machine learning classification model using supervised learning
  # 
  # Uses stochastic gradient descent (SGD) optimization with backpropagation
  # to adjust model weights based on training data. The training process
  # iteratively improves model accuracy by minimizing prediction errors.
  #
  # @param [Array<Array<Float>>] features Training input data where each
  #   sub-array represents feature values for one training example
  # @param [Array<Integer>] labels Expected output classifications corresponding  
  #   to each feature vector (0-based class indices)
  # @return [TrainedModel] Model with optimized weights ready for predictions
  # @see https://en.wikipedia.org/wiki/Backpropagation for algorithm details
  def train(features, labels)
    # Implementation with clear variable names and comments
  end
end

Reference

RDoc Markup Reference

Syntax Output Usage
*bold* bold Emphasis in descriptions
_italic_ italic Secondary emphasis
+code+ code Inline code references
[link text](URL) Hyperlink External references
{ClassName} Cross-reference Internal code links
* item • item Bulleted lists
1. item 1. item Numbered lists

YARD Tag Reference

Tag Syntax Purpose
@param @param [Type] name Description Method parameters
@return @return [Type] Description Return values
@raise @raise [ExceptionType] Description Possible exceptions
@example @example Title\n code Usage examples
@see @see ClassName#method Related references
@since @since 1.2.0 Version availability
@deprecated @deprecated Use {#new_method} instead Deprecation notices
@yield @yield [Type] Description Block parameters
@yieldparam @yieldparam [Type] name Description Block parameter details
@yieldreturn @yieldreturn [Type] Description Block return values

Type Specification Conventions

Type Pattern Description Example
[String] Single type Basic string parameter
[String, nil] Union types Optional string parameter
[Array<String>] Generic collections Array of strings
[Hash<Symbol,Object>] Hash with key/value types Options hash
[#to_s] Duck typing Objects responding to method
[Boolean] True or false values Flag parameters
[void] No return value Procedures

Documentation Generation Commands

Command Purpose Key Options
rdoc Generate RDoc documentation --main, --title, --output-dir
yardoc Generate YARD documentation --output-dir, --markup, --template
yard server Development documentation server --port, --reload
yard stats Documentation coverage statistics --list-undoc

Configuration Files

File Purpose Format
.yardopts YARD command-line options One option per line
.document RDoc file inclusion patterns Glob patterns
yard_config.yml YARD project configuration YAML format

Visibility Modifiers

Modifier YARD Syntax RDoc Syntax Effect
Public Default Default Included in documentation
Protected @!visibility protected # :protected: Conditionally included
Private @!visibility private # :private: Excluded by default
Hidden @!visibility private # :nodoc: Never included

Error Documentation Patterns

Exception Category Documentation Approach Example
Input validation Document invalid input scenarios @raise [ArgumentError] When email format is invalid
Resource unavailability Document dependency failures @raise [ConnectionError] When database is unreachable
Permission issues Document authorization requirements @raise [UnauthorizedError] When user lacks admin privileges
State conflicts Document timing and state issues @raise [StateError] When object is already finalized
External service errors Document third-party failures @raise [ServiceError] When payment gateway is unavailable