OptionParser
Part of Ruby's standard library, making it a readily available and simple choice for basic argument parsing tasks.
Framework
OptionParser
Overview
OptionParser is part of Ruby's standard library, making it a readily available and simple choice for basic command-line argument parsing tasks. As a standard library, it continues to be used in simple scripts as it can be used without additional dependencies. It has a low learning curve and is suitable for basic Ruby CLI tool development.
Details
OptionParser is a command-line argument parsing library included with Ruby by default. It can be used without adding external gems and provides basic option parsing functionality. With its simple API and lightweight implementation, it's suitable for developing small CLI tools.
Key Features
- Standard Library: No additional gem installation required
- Lightweight: Minimal overhead
- Basic Functionality: Sufficient option parsing features
- Automatic Help Generation: Automatic help message generation
- Type Conversion: Automatic conversion to strings, numbers, arrays
- Validation: Basic value validation
- Short/Long Form: Supports both -v and --verbose
Pros and Cons
Pros
- No Dependencies: No additional installation required as standard library
- Low Learning Curve: Simple and easy-to-understand API
- Lightweight: Low memory usage and performance overhead
- Stability: Long-term support as Ruby standard library
- Sufficient Features: Adequate for basic CLI tools
Cons
- Feature Limitations: Advanced features are inferior to other libraries
- No Subcommand Support: Not suitable for complex CLI structures
- Limited Extensibility: Limited customization capabilities
- Not Modern: Doesn't support latest CLI design patterns
Key Links
Usage Examples
Basic Usage
#!/usr/bin/env ruby
require 'optparse'
# Hash to store options
options = {}
# Create OptionParser instance
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options] file"
# String option
opts.on('-n', '--name NAME', 'Specify name') do |name|
options[:name] = name
end
# Numeric option
opts.on('-c', '--count COUNT', Integer, 'Repeat count') do |count|
options[:count] = count
end
# Flag option
opts.on('-v', '--verbose', 'Verbose output') do
options[:verbose] = true
end
# Help option
opts.on('-h', '--help', 'Show help') do
puts opts
exit
end
end
# Parse arguments
begin
opt_parser.parse!(ARGV)
rescue OptionParser::InvalidOption => e
puts "Error: #{e.message}"
puts opt_parser
exit 1
end
# Remaining arguments (like filenames)
files = ARGV
# Use options
name = options[:name] || 'World'
count = options[:count] || 1
verbose = options[:verbose]
# Execute
count.times do |i|
puts "Hello, #{name}!"
puts "Execution count: #{i + 1}" if verbose
end
if files.any?
puts "Processing files: #{files.join(', ')}"
end
Advanced Example
#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
# Object to store options
options = OpenStruct.new
options.verbose = false
options.format = 'txt'
options.output = nil
options.force = false
opt_parser = OptionParser.new do |opts|
opts.banner = "File Processing Tool v1.0\nUsage: #{$0} [options] input_files..."
opts.separator ""
opts.separator "Basic options:"
# Required option (checked later)
opts.on('-o', '--output FILE', 'Output filename') do |output|
options.output = output
end
# Choice selection
opts.on('-f', '--format FORMAT', %w[txt csv json xml],
'Output format (txt, csv, json, xml)') do |format|
options.format = format
end
# Numeric range
opts.on('-l', '--limit LIMIT', Integer, 'Processing limit (1-1000)') do |limit|
if limit < 1 || limit > 1000
raise OptionParser::InvalidArgument, "Limit must be in range 1-1000"
end
options.limit = limit
end
# Array option
opts.on('-t', '--tags TAG1,TAG2,TAG3', Array, 'Tag list (comma-separated)') do |tags|
options.tags = tags
end
# Regex option
opts.on('-p', '--pattern REGEX', Regexp, 'Filter pattern (regex)') do |pattern|
options.pattern = pattern
end
opts.separator ""
opts.separator "Flag options:"
opts.on('-v', '--verbose', 'Verbose output') do
options.verbose = true
end
opts.on('-q', '--quiet', 'Quiet mode') do
options.quiet = true
end
opts.on('--force', 'Force execution') do
options.force = true
end
opts.on('--dry-run', 'Don\'t actually execute') do
options.dry_run = true
end
opts.separator ""
opts.separator "Other:"
opts.on_tail('-h', '--help', 'Show this help') do
puts opts
exit
end
opts.on_tail('--version', 'Show version') do
puts "File Processing Tool v1.0"
exit
end
end
# Parse arguments and handle errors
begin
opt_parser.parse!(ARGV)
rescue OptionParser::InvalidOption => e
STDERR.puts "Error: #{e.message}"
STDERR.puts opt_parser
exit 1
rescue OptionParser::InvalidArgument => e
STDERR.puts "Error: #{e.message}"
exit 1
end
# Check required parameters
if ARGV.empty?
STDERR.puts "Error: No input files specified"
STDERR.puts opt_parser
exit 1
end
# Check mutually exclusive options
if options.verbose && options.quiet
STDERR.puts "Error: --verbose and --quiet cannot be specified together"
exit 1
end
# Display configuration
unless options.quiet
puts "Processing configuration:"
puts " Input files: #{ARGV.join(', ')}"
puts " Output file: #{options.output || 'stdout'}"
puts " Output format: #{options.format}"
puts " Limit: #{options.limit || 'unlimited'}"
puts " Tags: #{options.tags&.join(', ') || 'none'}"
puts " Pattern: #{options.pattern || 'none'}"
puts " Verbose output: #{options.verbose ? 'yes' : 'no'}"
puts " Dry run: #{options.dry_run ? 'yes' : 'no'}"
puts
end
# Execute file processing
ARGV.each do |input_file|
unless File.exist?(input_file)
STDERR.puts "Warning: File not found: #{input_file}"
next
end
puts "Processing: #{input_file}" if options.verbose
# File processing simulation
unless options.dry_run
lines = File.readlines(input_file)
# Pattern filtering
if options.pattern
lines = lines.select { |line| line.match?(options.pattern) }
end
# Apply limit
if options.limit
lines = lines.first(options.limit)
end
# Output processing
output_content = case options.format
when 'csv'
lines.map { |line| "\"#{line.chomp}\"" }.join(",\n")
when 'json'
require 'json'
lines.map(&:chomp).to_json
when 'xml'
"<lines>\n" + lines.map { |line| " <line>#{line.chomp}</line>" }.join("\n") + "\n</lines>"
else
lines.join
end
# Output
if options.output
File.write(options.output, output_content)
puts "Output complete: #{options.output}" unless options.quiet
else
puts output_content
end
end
end
puts "Processing complete" unless options.quiet
Execution Examples
# Basic usage
ruby script.rb --name "Ruby" --count 3 --verbose file1.txt file2.txt
# With configuration file
ruby configurable_app.rb --config config.yml --port 9000
# Validation example
ruby validated_app.rb --email test@example.com --url https://example.com --number 50