CLI Scripts with OptionParser & ARGV
A command-line script reads its arguments from the ARGV array, and Ruby's standard-library OptionParser turns raw flags into a clean options hash with validation and help text built in.
Learn CLI Scripts with OptionParser & ARGV in our free Ruby course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…
Part of the free Ruby course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll build a real CLI tool that parses flags, coerces types, handles errors, and returns proper exit codes.
What You'll Learn in This Lesson
1️⃣ ARGV: The Raw Arguments
Every Ruby script gets its command-line arguments in the built-in ARGV array, already split by the shell. For simple tools you can read it directly — separating flags from positional values by hand — but this gets brittle fast, which is exactly why OptionParser exists.
2️⃣ OptionParser: Flags into a Hash
Require 'optparse' , build an OptionParser , and register each flag with opts.on(...) . Pass a type like Integer and OptionParser coerces the value for you; set defaults on the hash beforehand. Then parse! fills the hash from the arguments.
3️⃣ Error Handling & Exit Codes
A robust CLI validates its input. OptionParser raises OptionParser::InvalidOption on unknown flags; rescue it, print a message to stderr with warn , and exit with a non-zero code so callers know it failed. A successful run should exit 0 .
🎯 Your Turn
The --upcase switch is declared but stores into the wrong key. Replace the ___ with the key set up in the defaults hash.
Parse a task-creation argv with a restricted --priority , a repeatable --tag , a --done switch, and a positional title. Run with ruby tasker.rb .
📋 Quick Reference — CLI & OptionParser
Practice quiz
What is ARGV in a Ruby script?
- The script's filename
- A hash of environment variables
- An array of the command-line arguments passed to the script
- The standard input stream
Answer: An array of the command-line arguments passed to the script. ARGV is a built-in array holding the command-line arguments, already split by the shell.
Which require loads OptionParser?
- require 'optparse'
- require 'optionparser'
- require 'argv'
- require 'options'
Answer: require 'optparse'. OptionParser lives in 'optparse' — require 'optparse' before using it.
Running ruby greet.rb Ada --loud gives ARGV equal to:
The script name is NOT in ARGV (that's $0); ARGV is ["Ada", "--loud"].
Passing Integer in opts.on("--count=N", Integer) does what?
- Limits the value to one digit
- Coerces the parsed value to an Integer automatically
- Requires the flag to be named Integer
- Nothing — it is ignored
Answer: Coerces the parsed value to an Integer automatically. Giving a type like Integer makes OptionParser coerce the flag's value to that type.
What is the difference between parse and parse!?
- parse! mutates the array, removing recognized flags and leaving positionals behind
- parse! is invalid
- parse! is faster but identical in behavior
- parse raises errors, parse! never does
Answer: parse! mutates the array, removing recognized flags and leaving positionals behind. parse! consumes recognized flags from the array, leaving the positional arguments behind.
Which exception does OptionParser raise on an unknown flag like --bogus?
- ArgumentError
- NoMethodError
- OptionParser::InvalidOption
- OptionParser::UnknownFlag
Answer: OptionParser::InvalidOption. An unregistered flag raises OptionParser::InvalidOption, which you can rescue.
In shell convention, what exit code signals SUCCESS?
- 1
- 0
- -1
- Any non-zero value
Answer: 0. Exit code 0 means success; any non-zero value signals an error to the shell.
After parse! consumes the flags, where are the positional arguments (like a title)?
- Lost forever
- In ENV
- In the options hash under :positional
- Whatever remains in the argv array after parsing
Answer: Whatever remains in the argv array after parsing. parse! leaves non-flag positional arguments behind in the array — read what's left.
How do you read one line of interactive input and strip the trailing newline?
- gets
- gets.chomp
- read.line
- input.next
Answer: gets.chomp. gets reads a line (including the newline); .chomp removes that trailing newline.
To collect a REPEATABLE flag like --tag a --tag b into an array, you should:
- Use a type of Array in opts.on
- It's impossible with OptionParser
- Push each value into an array inside the opts.on block
- Use parse instead of parse!
Answer: Push each value into an array inside the opts.on block. Push each parsed value into an array inside the block so repeated flags accumulate.