Skip to content

Ruby Comments

Comments are text in code that won't be executed by the interpreter, used to explain code functionality, record information, or temporarily disable code. Good commenting habits are an important part of writing high-quality code. This chapter will introduce in detail the various commenting methods in Ruby and their best practices.

💬 Single-Line Comments

Basic Syntax

In Ruby, use the # symbol to create single-line comments. All content from # to the end of the line will be ignored.

ruby
# This is a single-line comment
puts "Hello, World!"  # This is also a comment, following code

# Calculate sum of two numbers
def add(a, b)
  a + b  # Return sum of two numbers
end

# Variable declaration
name = "Zhang San"  # User name
age = 25       # User age

Comment Placement

ruby
# Comment above code line (recommended)
def calculate_area(length, width)
  length * width
end

def calculate_volume(length, width, height)
  area = length * width  # Calculate base area first
  area * height          # Multiply by height to get volume
end

# End-of-line comments (use sparingly)
counter = 0  # Initialize counter
counter += 1 # Increment counter

📝 Multi-Line Comments

Using =begin and =end

Ruby provides =begin and =end to create multi-line comment blocks:

ruby
=begin
This is a multi-line comment block
Can contain multiple lines of content
Used to explain complex code logic in detail
=end
puts "Hello, World!"

=begin
Complex algorithm explanation:
1. First initialize data structure
2. Then perform data processing
3. Finally output results
=end
def complex_algorithm
  # Algorithm implementation
end

Notes

ruby
# =begin and =end must start at the beginning of the line, no spaces before
# Correct写法:
=begin
Correct comment block
=end

# Incorrect写法 (won't be recognized as comment):
  =begin
  Incorrect comment block
  =end

🎯 Comment Uses

1. Code Explanation

ruby
class BankAccount
  def initialize(owner, initial_balance = 0)
    @owner = owner
    @balance = initial_balance
  end
  
  # Deposit method
  # Parameters: amount - deposit amount
  # Returns: Boolean - whether operation succeeded
  def deposit(amount)
    if amount > 0
      @balance += amount
      log_transaction("Deposit", amount)
      true
    else
      puts "Deposit amount must be greater than 0"
      false
    end
  end
  
  # Withdrawal method
  # Parameters: amount - withdrawal amount
  # Returns: Boolean - whether operation succeeded
  def withdraw(amount)
    if amount > 0 && amount <= @balance
      @balance -= amount
      log_transaction("Withdrawal", amount)
      true
    elsif amount > @balance
      puts "Insufficient balance"
      false
    else
      puts "Withdrawal amount must be greater than 0"
      false
    end
  end
  
  private
  
  # Log transaction
  # Parameters: type - transaction type, amount - transaction amount
  def log_transaction(type, amount)
    timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
    puts "[#{timestamp}] #{type}: #{amount}, Balance: #{@balance}"
  end
end

2. Temporarily Disable Code

ruby
def process_data(data)
  # Temporarily disable debug output
  # puts "Processing data: #{data}"
  
  result = data.map { |item| item.upcase }
  
  # puts "Processing result: #{result}"  # Temporarily disabled
  
  result
end

# Completely disable a block of code
=begin
def old_method
  # Old implementation
  puts "This is old method"
end

def deprecated_function
  # Deprecated functionality
  puts "Not recommended method"
end
=end

3. TODO Comments

ruby
class DataProcessor
  def initialize
    @data = []
  end
  
  # TODO: Implement data validation feature
  def validate_data
    # To be implemented
  end
  
  # FIXME: Fix boundary condition handling
  def process_item(item)
    # Current implementation may have issues
    item.process
  end
  
  # HACK: Temporary solution, needs refactoring
  def quick_fix
    # Temporary fix code
  end
  
  # NOTE: This method has special behavior
  def special_behavior
    # Special handling logic
  end
  
  # OPTIMIZE: Performance can be optimized
  def slow_operation
    # Time-consuming operation
  end
end

📚 Documentation Comments

RDoc Format

Ruby uses RDoc tool to generate documentation, supporting specific comment formats:

ruby
# Calculator class
# Provides basic mathematical operations
class Calculator
  # Create a new calculator instance
  def initialize
    @history = []
  end
  
  # Addition operation
  # 
  # Parameters:
  #   a - First addend (Numeric)
  #   b - Second addend (Numeric)
  # 
  # Returns:
  #   Sum of two numbers (Numeric)
  # 
  # Example:
  #   calc = Calculator.new
  #   result = calc.add(2, 3)  # => 5
  def add(a, b)
    result = a + b
    @history << "#{a} + #{b} = #{result}"
    result
  end
  
  # Subtraction operation
  # 
  # Parameters:
  #   a - Minuend (Numeric)
  #   b - Subtrahend (Numeric)
  # 
  # Returns:
  #   Difference of two numbers (Numeric)
  def subtract(a, b)
    result = a - b
    @history << "#{a} - #{b} = #{result}"
    result
  end
  
  # Get calculation history
  # 
  # Returns:
  #   Calculation history array (Array<String>)
  def history
    @history.dup
  end
end

YARD Format

YARD is another popular Ruby documentation generation tool, supporting richer markup syntax:

ruby
# @author Zhang San
# @since 1.0.0
class User
  # @return [String] User name
  attr_accessor :name
  
  # @return [Integer] User age
  attr_accessor :age
  
  # Create new user
  # 
  # @param name [String] User name
  # @param age [Integer] User age
  # @param email [String] User email
  def initialize(name, age, email = nil)
    @name = name
    @age = age
    @email = email
  end
  
  # Check if user is an adult
  # 
  # @return [Boolean] Returns true if age is greater than or equal to 18
  # 
  # @example
  #   user = User.new("Zhang San", 20)
  #   user.adult?  # => true
  def adult?
    @age >= 18
  end
  
  # @!attribute [r] created_at
  # @return [Time] User creation time
  attr_reader :created_at
end

🎨 Comment Style Guide

1. Comment Content

ruby
# Good comments: Explain why, not what
# Due to API limitation, need to validate email format before sending
if valid_email?(user.email)
  send_welcome_email(user)
end

# Avoid obvious comments
# x = x + 1  # Increment x value (unnecessary comment)

# Good comments: Explain complex logic
# Use quicksort algorithm, average time complexity O(n log n)
def quick_sort(array)
  return array if array.length <= 1
  pivot = array.delete_at(rand(array.length))
  left, right = array.partition { |x| x < pivot }
  quick_sort(left) + [pivot] + quick_sort(right)
end

2. Comment Format

ruby
# Good comment format: Capitalize first letter, end with punctuation
# Calculate user age.

# Multi-line comments maintain consistent indentation
# This is a longer comment,
# used to explain complex business logic,
# requiring multiple lines to fully describe.

# Parameter descriptions use consistent format
# Parameters:
#   name - User name
#   age  - User age

3. Chinese Comments

ruby
class DataProcessor
  # Initialize data processor
  # Set default processing parameters
  def initialize
    @data_list = []
    @processing_status = :pending
  end
  
  # Add data item
  # 
  # Parameters:
  #   item - Data item to add
  # 
  # Returns:
  #   Boolean - Whether addition succeeded
  def add_item(item)
    if item.nil?
      puts "Error: Item cannot be empty"
      return false
    end
    
    @data_list << item
    @processing_status = :has_data if @data_list.length == 1
    true
  end
  
  # Process all data
  # Process each item in the data list according to predefined rules
  def process_data
    return if @data_list.empty?
    
    @data_list.each_with_index do |item, index|
      puts "Processing item #{index + 1}: #{item}"
      # Actual processing logic
    end
    
    @processing_status = :completed
  end
end

🛠️ Comment Tools and Techniques

1. Comment Templates

ruby
# Method comment template
# 
# Method function summary
# 
# Parameters:
#   param_name - Parameter description (type)
# 
# Returns:
#   Return value description (type)
# 
# Exceptions:
#   ExceptionClass - Exception description
# 
# Example:
#   Code example
def method_name(param_name)
  # Method implementation
end

# Class comment template
# 
# Class function summary
# 
# @author Author name
# @version Version number
# @since Starting version
class ClassName
  # Class implementation
end

2. Conditional Comments

ruby
# Detailed logs in debug mode
if ENV['DEBUG'] == 'true'
  # puts "Debug info: #{variable}"
end

# Special handling in development environment
if ENV['RUBY_ENV'] == 'development'
  # Development environment-specific code
end

# Version-specific code
if RUBY_VERSION >= '2.7'
  # Ruby 2.7+ features
else
  # Compatible old version implementation
end

3. Comment Marks

ruby
def complex_method
  # TODO: Implement caching mechanism
  # FIXME: Fix memory leak issue
  # HACK: Temporarily bypass API limitation
  # NOTE: Implementation here may need optimization
  # OPTIMIZE: Consider using more efficient algorithm
  # WARNING: This method may have issues under high concurrency
  # DEPRECATED: This method will be removed in next version
  
  # Method implementation
end

🧪 Comment Practice Examples

Complete Comment Example

ruby
# =============================================================================
# User Management System
# 
# Provides user registration, login, permission management and other functions
# 
# @author Development Team
# @version 1.2.0
# @since 2023-01-01
# =============================================================================
class UserManager
  # User role constants
  ROLES = %i[admin user guest].freeze
  
  # Initialize user manager
  # 
  # @param config [Hash] Configuration options
  # @option config [Boolean] :enable_logging Whether to enable logging (default: true)
  # @option config [Integer] :max_login_attempts Maximum login attempts (default: 3)
  def initialize(config = {})
    @users = {}
    @config = {
      enable_logging: true,
      max_login_attempts: config[:max_login_attempts] || 3
    }
    @login_attempts = Hash.new(0)
  end
  
  # User registration
  # 
  # @param username [String] Username
  # @param password [String] Password
  # @param email [String] Email address
  # @param role [Symbol] User role (:admin, :user, :guest)
  # 
  # @return [Boolean] Whether registration succeeded
  # 
  # @raise [ArgumentError] Thrown when parameters are invalid
  # 
  # @example
  #   manager = UserManager.new
  #   manager.register("zhangsan", "password123", "zhangsan@example.com")
  def register(username, password, email, role = :user)
    # Parameter validation
    raise ArgumentError, "Username cannot be empty" if username.nil? || username.empty?
    raise ArgumentError, "Password cannot be empty" if password.nil? || password.empty?
    raise ArgumentError, "Invalid email format" unless valid_email?(email)
    raise ArgumentError, "Invalid user role" unless ROLES.include?(role)
    
    # Check if username already exists
    if @users.key?(username)
      log("Registration failed: Username already exists - #{username}")
      return false
    end
    
    # Create new user
    @users[username] = {
      password: hash_password(password),
      email: email,
      role: role,
      created_at: Time.now,
      last_login: nil
    }
    
    log("User registration successful: #{username}")
    true
  end
  
  # User login
  # 
  # @param username [String] Username
  # @param password [String] Password
  # 
  # @return [Boolean] Whether login succeeded
  def login(username, password)
    user = @users[username]
    
    # Check if user exists
    unless user
      log("Login failed: User does not exist - #{username}")
      record_failed_login(username)
      return false
    end
    
    # Check login attempts
    if @login_attempts[username] >= @config[:max_login_attempts]
      log("Login failed: Exceeded maximum attempts - #{username}")
      return false
    end
    
    # Verify password
    if verify_password(password, user[:password])
      user[:last_login] = Time.now
      @login_attempts[username] = 0
      log("Login successful: #{username}")
      true
    else
      log("Login failed: Incorrect password - #{username}")
      record_failed_login(username)
      false
    end
  end
  
  # Get user information
  # 
  # @param username [String] Username
  # 
  # @return [Hash, nil] User information hash or nil
  def get_user_info(username)
    user = @users[username]
    return nil unless user
    
    # Return safe information without password
    user.reject { |key, _| key == :password }
  end
  
  private
  
  # Validate email format
  # 
  # @param email [String] Email address
  # 
  # @return [Boolean] Whether email format is valid
  def valid_email?(email)
    # Simple email validation regex
    email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
  end
  
  # Password hash
  # 
  # @param password [String] Raw password
  # 
  # @return [String] Hashed password
  def hash_password(password)
    # TODO: Implement real password hashing (using BCrypt, etc.)
    require 'digest'
    Digest::SHA256.hexdigest(password)
  end
  
  # Verify password
  # 
  # @param input_password [String] Input password
  # @param stored_hash [String] Stored hashed password
  # 
  # @return [Boolean] Whether passwords match
  def verify_password(input_password, stored_hash)
    hash_password(input_password) == stored_hash
  end
  
  # Record failed login attempt
  # 
  # @param username [String] Username
  def record_failed_login(username)
    @login_attempts[username] += 1
  end
  
  # Log message
  # 
  # @param message [String] Log message
  def log(message)
    return unless @config[:enable_logging]
    timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
    puts "[#{timestamp}] #{message}"
  end
end

🎯 Comment Best Practices

1. When to Add Comments

ruby
# Good comment scenarios:

# 1. Complex algorithm explanation
# Use Dijkstra algorithm to calculate shortest path
def dijkstra(graph, start_node)
  # Algorithm implementation
end

# 2. Business logic explanation
# Calculate discount rate based on user level
# Regular user: 0%, Gold user: 5%, Diamond user: 10%
def calculate_discount(user_level)
  case user_level
  when :regular then 0
  when :gold then 0.05
  when :diamond then 0.10
  else 0
  end
end

# 3. Non-obvious code
# Due to floating point precision issues, use BigDecimal for accurate calculation
require 'bigdecimal'
def precise_calculation(a, b)
  BigDecimal(a.to_s) + BigDecimal(b.to_s)
end

2. When to Avoid Comments

ruby
# Avoid comment scenarios:

# 1. Obvious code
x = 0  # Set x to 0 (unnecessary comment)

# 2. Outdated comments
# Calculate user points (actual code has changed to calculate user level)
def calculate_user_level(user)
  # Implementation
end

# 3. Redundant comments
# Loop through array
array.each do |item|
  # Process each item
  process_item(item)
end

3. Maintain Comments

ruby
# Regularly check and update comments
class DataProcessor
  # Old comment: Use SHA1 hashing algorithm
  # New comment: Use SHA256 hashing algorithm (updated 2023-06-01)
  def hash_data(data)
    Digest::SHA256.hexdigest(data)
  end
  
  # TODO(2023-12-31): Implement caching mechanism
  # FIXME(Zhang San): Fix concurrent access issue
  # OPTIMIZE(Li Si): Optimize big data processing performance
end

📚 Next Steps

After mastering Ruby comments, it is recommended to continue learning:

Continue your Ruby learning journey!

Content is for learning and research only.