The Complete Ruby Programming Guide
Installation · Core Concepts · OOP · File I/O · Exception Handling
A comprehensive, beginner-to-intermediate guide to the Ruby programming language — covering installation on every major platform, variables, data types, strings, numbers, arrays, hashes, methods, loops, classes, inheritance, modules, file handling, and exception handling. Includes real-world examples, mini-games, and practical applications.
Table of Contents
- What is Ruby?
- Advantages and Disadvantages of Ruby
- Installing Ruby — Windows, macOS, Linux, Termux (32-bit and 64-bit)
- Setting Up a Text Editor
- Your First Ruby Program
- Print Statements: puts vs print
- Variables
- Data Types
- Working with Strings
- Working with Numbers
- Getting User Input
- Building a Calculator
- Mad Libs Game
- Arrays
- Hashes
- Methods and Return Values
- If Statements and Comparisons
- Case Expressions
- While Loops and the Guessing Game
- For Loops and the Exponent Method
- Comments
- Reading and Writing Files
- Exception Handling
- Classes and Objects
- The Initialize Method
- Instance Methods
- Multiple Choice Quiz Project
- Inheritance
- Modules
1. What is Ruby?
Ruby is a dynamic, open-source, object-oriented programming language created by Yukihiro Matsumoto (widely known as “Matz”) in Japan in the mid-1990s and first publicly released in 1995. Matz designed Ruby with a philosophy centered on developer happiness — the language is meant to be natural to read and easy to write. Ruby draws inspiration from Perl, Smalltalk, Eiffel, Ada, and Lisp, blending features from each into a language that feels both familiar and elegant.
Ruby gained massive global popularity in the mid-2000s largely because of Ruby on Rails — a full-stack web application framework built entirely in Ruby. Rails introduced the concept of “convention over configuration”, dramatically speeding up web development and influencing frameworks in almost every other language. Companies like GitHub, Shopify, Airbnb, Basecamp, and Twitter (in its early days) were all built using Ruby on Rails.
Beyond web development, Ruby is used for scripting and automation, data processing, rapid prototyping, DevOps tooling (tools like Chef and Puppet are written in Ruby), and general-purpose programming. Its clean, readable syntax means a beginner can write meaningful programs quickly, while its depth and expressiveness keep experienced developers productive.
Key Characteristics of Ruby
- Fully Object-Oriented: In Ruby, everything is an object — numbers, strings, booleans, nil. There are no primitive types.
- Dynamically Typed: You do not declare variable types. Ruby figures out the type at runtime.
- Garbage Collected: Memory management is automatic. You do not need to manually allocate or free memory.
- Interpreted: Ruby code is executed line by line by the Ruby interpreter, making it easy to test and debug.
- Expressive Syntax: Ruby reads almost like plain English in many cases, reducing the mental overhead of understanding code.
- Rich Standard Library: Ruby ships with a large standard library covering networking, file I/O, cryptography, date/time handling, and much more.
- Active Ecosystem: RubyGems is Ruby’s package manager, hosting over 170,000 libraries (called gems) for virtually any task.
2. Advantages and Disadvantages of Ruby
Advantages
| Advantage | Details |
|---|---|
| Beginner-Friendly | Ruby’s clean, English-like syntax minimizes boilerplate, making it one of the best first languages. |
| Rapid Development | Fewer lines of code compared to Java or C++. Developers build features faster. |
| Everything is an Object | Consistent OOP model. Methods can be called on literally any value, including integers and nil. |
| Strong Community | Large, welcoming community with extensive tutorials, gems, and open-source projects. |
| Ruby on Rails | Rails remains one of the most productive web frameworks ever built, with massive adoption. |
| Open Source | Completely free to use, modify, and distribute. No licensing fees. |
| Metaprogramming | Ruby allows programs to write and modify code at runtime — powerful for DSLs and frameworks. |
| Gems Ecosystem | RubyGems provides access to over 170,000 libraries covering almost any task imaginable. |
| Cross-Platform | Runs on Windows, macOS, Linux, and even mobile environments like Termux. |
| Great for Prototyping | Ideas can be turned into working code quickly, making Ruby ideal for MVPs and hackathons. |
Disadvantages
| Disadvantage | Details |
|---|---|
| Performance | Ruby is slower than compiled languages like C, Java, or Go. Not ideal for CPU-intensive tasks. |
| Concurrency | The Global Interpreter Lock (GIL) in MRI Ruby limits true parallel threading. |
| Runtime Errors | Dynamic typing means type errors only surface at runtime, not compile time. |
| Memory Usage | Ruby applications tend to use more memory compared to languages like Go or Rust. |
| Boot Time | Rails applications can be slow to start up, making development feedback loops longer. |
| Mobile Development | Limited native mobile support compared to Swift (iOS) or Kotlin (Android). |
| Job Market Shift | While still in demand, Python and JavaScript have overtaken Ruby in raw job postings. |
| Debugging Complexity | Dynamic features like metaprogramming can make tracing bugs more difficult. |
3. Installing Ruby
Ruby can be installed on every major operating system. Below are complete installation instructions for Windows, macOS, Linux, and Termux, covering both 32-bit and 64-bit systems.
3.1 Installing Ruby on Windows (32-bit and 64-bit)
Windows does not come with Ruby pre-installed. The easiest way is to use RubyInstaller, an official project that bundles Ruby, the MSYS2 toolchain, and the DevKit into a single installer.
Step 1 — Download RubyInstaller
Go to https://rubyinstaller.org/downloads/. Always choose the Ruby+Devkit version. For 64-bit Windows choose the x64 installer. For 32-bit Windows choose the x86 installer.
Step 2 — Run the Installer
Double-click the downloaded .exe file. Accept the license. On the installation options screen, check all boxes including “Add Ruby executables to your PATH”. This is critical — without it you cannot run Ruby from the command prompt.
Step 3 — Install MSYS2 and Development Toolchain
When the installer finishes, a command prompt window opens automatically with three options. Enter each number in order and wait for each to finish:
1 - MSYS2 base installation
2 - MSYS2 system update
3 - MSYS2 and MINGW development toolchain
Running all three in order prevents dependency errors.
Step 4 — Verify the Installation
Open Command Prompt and run:
ruby -v
gem -v
You should see a Ruby version number. If you see “ruby is not recognized”, restart your command prompt or check that Ruby was added to PATH during installation.
3.2 Installing Ruby on macOS
macOS ships with a system version of Ruby pre-installed, but it is usually outdated and Apple discourages relying on it. The recommended approach is to install a newer version via rbenv or RVM.
Check existing Ruby version:
ruby -v
Method 1 — Install via Homebrew (Recommended)
# Install Homebrew if you don't have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install rbenv and ruby-build
brew install rbenv ruby-build
# Add rbenv to your shell
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
source ~/.zshrc
# Install and set Ruby version
rbenv install 3.3.0
rbenv global 3.3.0
ruby -v
Method 2 — Install via RVM
\curl -sSL https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
rvm install ruby --latest
rvm use ruby --default
ruby -v
Note: For Apple Silicon Macs (M1/M2/M3), ensure Homebrew is installed for ARM (arm64) architecture. rbenv will automatically install the correct native Ruby binary.
3.3 Installing Ruby on Linux
Ubuntu / Debian (apt) — 64-bit and 32-bit
# Update package index
sudo apt update
# Install Ruby
sudo apt install ruby-full -y
# Verify
ruby -v
gem -v
For a more up-to-date version, use rbenv:
sudo apt install git curl libssl-dev libreadline-dev zlib1g-dev \
autoconf bison build-essential libyaml-dev libffi-dev libgdbm-dev -y
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
rbenv install 3.3.0
rbenv global 3.3.0
ruby -v
Fedora / RHEL / CentOS (dnf/yum)
# Fedora
sudo dnf install ruby ruby-devel -y
# CentOS / RHEL
sudo yum install epel-release -y
sudo yum install ruby -y
ruby -v
Arch Linux / Manjaro
sudo pacman -S ruby
ruby -v
32-bit Linux Note
On 32-bit Linux systems the above commands work identically. Ruby fully supports i386/i686 architectures. To check your system architecture:
uname -m
# i686 = 32-bit x86_64 = 64-bit
3.4 Installing Ruby on Termux (Android)
Termux is a free Android terminal emulator that lets you run command-line tools on your phone without root access. Available on F-Droid (recommended) and Google Play Store.
# Step 1: Update packages
pkg update && pkg upgrade -y
# Step 2: Install Ruby
pkg install ruby -y
# Step 3: Verify
ruby -v
gem -v
# Step 4: Run your first script
echo 'puts "Hello from Termux!"' > hello.rb
ruby hello.rb
Termux automatically installs the correct binary for your device architecture (32-bit armv7 or 64-bit aarch64). You can also install gems normally: gem install rails
4. Setting Up a Text Editor
You can write Ruby in any text editor. Popular choices include:
- VS Code (free, most popular) — install the “Ruby” and “Ruby Solargraph” extensions.
- Atom (free) — install the “atom-runner” plugin to run Ruby directly with Ctrl+R.
- RubyMine (paid, JetBrains) — the most feature-complete Ruby IDE.
- Sublime Text — lightweight with good Ruby support via packages.
For VS Code, open the Extensions panel, search for “Ruby Solargraph”, and install it. This gives you auto-completion, inline documentation, and error highlighting while you type.
5. Your First Ruby Program
Create a file called hello.rb and add the following:
puts "Hello, World!"
Run it from the terminal:
ruby hello.rb
Output:
Hello, World!
Ruby reads your file from top to bottom and executes each instruction in order. This linear execution model is the foundation of how all Ruby programs work.
6. Print Statements: puts vs print
Ruby gives you two primary ways to display output:
puts
Prints the value and adds a new line at the end. The next output starts on a fresh line.
puts "Hello"
puts "World"
# Output:
# Hello
# World
Prints the value without adding a new line. Whatever comes next appears on the same line.
print "Hello"
print " World"
# Output:
# Hello World
Special Characters Inside Strings
\n— insert a new line inside a string\"— print a literal quotation mark\t— insert a tab character
puts "Line 1\nLine 2"
# Output:
# Line 1
# Line 2
7. Variables
A variable is a named container that stores a piece of data. Variables let you store information once and refer to it many times throughout your program.
character_name = "John"
character_age = 35
puts ("There once was a man named " + character_name)
puts ("He was " + character_age.to_s + " years old.")
Why Variables Matter
Imagine a story that mentions a character’s name 50 times. Without variables, changing that name means editing 50 places. With a variable, you change it in one place and every reference updates automatically.
name = "Mike"
puts name # Output: Mike
name = "Tom"
puts name # Output: Tom
Variable Naming Rules
- Must start with a lowercase letter or underscore.
- Use snake_case for multi-word names:
first_name,user_age. - Names are case-sensitive:
ageandAgeare different variables. - Names should be descriptive —
character_nameis better thancn. - Cannot use Ruby reserved keywords:
if,else,end,def,class, etc.
8. Data Types
Ruby supports several built-in data types. The type of data determines what operations you can perform on it.
| Type | Description | Example |
|---|---|---|
| String | Plain text, enclosed in quotes. | "Hello, Ruby!" |
| Integer | Whole numbers, positive or negative. | 42, -7, 0 |
| Float | Decimal/floating point numbers. | 3.14, -0.5 |
| Boolean | True or false values only. | true, false |
| Nil | Represents the absence of a value. | nil |
| Symbol | Immutable identifier, like a named constant. | :name, :status |
| Array | Ordered list of values. | [1, "a", true] |
| Hash | Key-value pairs, like a dictionary. | {name: "John"} |
name = "Alice" # String
age = 30 # Integer
gpa = 3.85 # Float
is_student = true # Boolean
middle_name = nil # Nil
9. Working with Strings
Strings are sequences of characters and one of the most commonly used data types in Ruby. Ruby provides a rich set of built-in methods to manipulate, search, and transform text.
Common String Methods
phrase = "Hello, Ruby Developer"
phrase.upcase # => "HELLO, RUBY DEVELOPER"
phrase.downcase # => "hello, ruby developer"
phrase.length # => 21
phrase.reverse # => "repoleveD ybuR ,olleH"
phrase.include?("Ruby") # => true
phrase.strip # removes leading/trailing whitespace
phrase[0] # => "H" (first character)
phrase[0, 5] # => "Hello" (5 chars from index 0)
phrase.index("Ruby") # => 7 (position of "Ruby")
String Interpolation
A cleaner way to embed variables inside strings using the #{} syntax:
name = "Alice"
age = 25
puts "Hello, #{name}! You are #{age} years old."
# Output: Hello, Alice! You are 25 years old.
Index Positions
Ruby strings are zero-indexed — the first character is at position 0. Negative indices count from the end: -1 is the last character, -2 is second to last.
10. Working with Numbers
Ruby handles both integers (whole numbers) and floats (decimal numbers). You can perform standard arithmetic as well as more advanced mathematical operations using Ruby’s built-in Math module.
Basic Arithmetic
puts 5 + 3 # => 8 (addition)
puts 10 - 4 # => 6 (subtraction)
puts 6 * 7 # => 42 (multiplication)
puts 15 / 4 # => 3 (integer division)
puts 15.0 / 4 # => 3.75 (float division)
puts 2 ** 10 # => 1024 (exponentiation)
puts 17 % 5 # => 2 (modulus — remainder)
Useful Number Methods
num = -42.7
num.abs # => 42.7 (absolute value)
num.round # => -43 (round to nearest integer)
num.ceil # => -42 (round up)
num.floor # => -43 (round down)
42.to_f # => 42.0 (integer to float)
42.to_s # => "42" (integer to string)
"3.14".to_f # => 3.14 (string to float)
"7".to_i # => 7 (string to integer)
Math Module
Math::sqrt(144) # => 12.0
Math::log(1) # => 0.0
Math::PI # => 3.141592653589793
Integer vs Float Rule
When both operands are integers, Ruby returns an integer — even for division. When at least one is a float, the result is a float. So 10 / 3 returns 3, but 10.0 / 3 returns 3.3333...
11. Getting User Input
The gets method pauses program execution and waits for the user to type something. chomp is almost always chained to gets to remove the trailing newline that gets added when the user presses Enter.
puts "What is your name?"
name = gets.chomp
puts "Hello, #{name}! Welcome to Ruby."
Getting Multiple Inputs
puts "Enter your name:"
name = gets.chomp
puts "Enter your age:"
age = gets.chomp.to_i
puts "#{name} is #{age} years old."
Important: Type Conversion
gets always returns a String. If you expect numeric input, always convert with .to_i (integer) or .to_f (float). Without converting, Ruby will concatenate strings instead of adding numbers.
num1 = gets.chomp.to_i # convert to integer
num2 = gets.chomp.to_f # convert to float
Note: Programs using gets must be run from the terminal, not from a plugin like atom-runner.
12. Building a Calculator
This project demonstrates user input, type conversion, and conditionals in a practical application.
Four-Function Calculator
puts "Enter first number:"
num1 = gets.chomp.to_f
puts "Enter operator (+, -, *, /):"
op = gets.chomp
puts "Enter second number:"
num2 = gets.chomp.to_f
if op == "+"
puts num1 + num2
elsif op == "-"
puts num1 - num2
elsif op == "*"
puts num1 * num2
elsif op == "/"
puts num1 / num2
else
puts "Invalid operator"
end
13. Mad Libs Game
Mad Libs is a word game where players fill blanks in a story with their own words. This project shows how to collect multiple inputs and embed them into a template.
puts "Enter a color:"
color = gets.chomp
puts "Enter a plural noun:"
plural_noun = gets.chomp
puts "Enter a celebrity name:"
celebrity = gets.chomp
puts "Roses are #{color}"
puts "#{plural_noun} are blue"
puts "I love #{celebrity}"
14. Arrays
An array is an ordered collection that can hold multiple values of any type. Arrays are one of the most important data structures in Ruby.
Creating and Accessing Arrays
friends = ["Kevin", "Karen", "Oscar", "Andy"]
puts friends[0] # => "Kevin" (first element)
puts friends[-1] # => "Andy" (last element)
puts friends[1, 2] # => ["Karen", "Oscar"] (2 elements from index 1)
Common Array Methods
friends.length # => 4
friends.include?("Kevin") # => true
friends.reverse # => ["Andy", "Oscar", "Karen", "Kevin"]
friends.sort # => alphabetical order
friends.push("Jim") # adds "Jim" to the end
friends.pop # removes and returns the last element
friends.first # => "Kevin"
friends.last # => last element
Modifying Elements
friends[0] = "Dwight"
puts friends[0] # => "Dwight"
Iterating Over an Array
friends.each do |friend|
puts "Hello, #{friend}!"
end
15. Hashes
A hash is a collection of key-value pairs, similar to a dictionary. Each key maps to exactly one value. Hashes are useful when data needs to be looked up by name rather than by position.
states = {
"Pennsylvania" => "PA",
"New York" => "NY",
"California" => "CA",
"Oregon" => "OR"
}
puts states["New York"] # => "NY"
puts states["California"] # => "CA"
Symbol Keys (Common Style)
person = {
name: "Alice",
age: 30,
occupation: "Developer"
}
puts person[:name] # => "Alice"
puts person[:age] # => 30
Iterating Over a Hash
states.each do |key, value|
puts "#{key} => #{value}"
end
16. Methods and Return Values
A method is a named block of reusable code. You define it once and call it wherever you need it, making your code more organized and easier to maintain.
Basic Method
def say_hello
puts "Hello, World!"
end
say_hello # => Hello, World!
Methods with Parameters
def greet(name, age)
puts "Hello, #{name}! You are #{age} years old."
end
greet("Mike", 30) # => Hello, Mike! You are 30 years old.
Default Parameter Values
def greet(name = "stranger", age = 0)
puts "Hello, #{name}! You are #{age}."
end
greet # => Hello, stranger! You are 0.
greet("Alice", 25) # => Hello, Alice! You are 25.
Return Values
def cube(num)
return num * num * num
end
puts cube(3) # => 27
puts cube(4) # => 64
Returning Multiple Values
def min_max(arr)
return arr.min, arr.max
end
low, high = min_max([3, 1, 8, 2, 5])
puts "Min: #{low}, Max: #{high}" # => Min: 1, Max: 8
17. If Statements and Comparisons
If statements allow your programs to make decisions. Based on whether a condition is true or false, different blocks of code will execute.
is_male = true
is_tall = false
if is_male && is_tall
puts "You are a tall male"
elsif is_male && !is_tall
puts "You are a short male"
elsif !is_male && is_tall
puts "You are tall but not male"
else
puts "You are neither male nor tall"
end
Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
== | Equal to | 5 == 5 # true |
!= | Not equal to | 5 != 3 # true |
> | Greater than | 7 > 3 # true |
< | Less than | 2 < 9 # true |
>= | Greater than or equal | 5 >= 5 # true |
<= | Less than or equal | 3 <= 4 # true |
&& | Logical AND | true && false # false |
|| | Logical OR | true || false # true |
! | Logical NOT | !true # false |
Max of Three Numbers
def max(num1, num2, num3)
if num1 >= num2 && num1 >= num3
return num1
elsif num2 >= num1 && num2 >= num3
return num2
else
return num3
end
end
puts max(5, 20, 3) # => 20
18. Case Expressions
A case expression is Ruby's cleaner alternative to long elsif chains when comparing the same variable against multiple values.
def get_day_name(day)
day_name = ""
case day
when "mon" then day_name = "Monday"
when "tue" then day_name = "Tuesday"
when "wed" then day_name = "Wednesday"
when "thu" then day_name = "Thursday"
when "fri" then day_name = "Friday"
when "sat" then day_name = "Saturday"
when "sun" then day_name = "Sunday"
else day_name = "Invalid abbreviation"
end
return day_name
end
puts get_day_name("fri") # => Friday
puts get_day_name("xyz") # => Invalid abbreviation
19. While Loops and the Guessing Game
A while loop repeatedly executes a block of code as long as its condition remains true. It is ideal when you do not know in advance how many times the loop needs to run.
Basic While Loop
index = 1
while index <= 5
puts index
index += 1
end
# Output: 1 2 3 4 5
Warning: An infinite loop occurs when the condition never becomes false. Always ensure your loop has a clear exit condition.
Guessing Game with Guess Limit
secret_word = "ruby"
guess = ""
guess_count = 0
guess_limit = 3
out_of_guesses = false
while guess != secret_word && !out_of_guesses
if guess_count < guess_limit
puts "Enter your guess:"
guess = gets.chomp
guess_count += 1
else
out_of_guesses = true
end
end
if out_of_guesses
puts "You lose! The word was #{secret_word}"
else
puts "You won! Great job!"
end
20. For Loops and the Exponent Method
For loops iterate over a collection or a range of values. They are best when you know exactly what you are iterating over.
Looping Over an Array
friends = ["Kevin", "Karen", "Oscar"]
# Using for
for friend in friends
puts friend
end
# Using .each (more idiomatic Ruby)
friends.each do |friend|
puts friend
end
Looping Over a Range
for i in 1..5
puts i
end
# Using times
6.times do |i|
puts i # prints 0 through 5
end
Exponent Method Using a Loop
def power(base, exp)
result = 1
exp.times do
result *= base
end
return result
end
puts power(2, 10) # => 1024
puts power(5, 3) # => 125
21. Comments
Comments are notes inside your code that Ruby ignores during execution. They are written for human readers — to explain why code was written a certain way or to temporarily disable lines during debugging.
# This is a single-line comment
puts "Hello" # This comment is after a line of code
# This line is commented out (disabled):
# puts "This will not run"
=begin
This is a
multi-line comment block.
Ruby will ignore all of this.
=end
Best practice: write code that is clear enough that it rarely needs comments. When you do use them, explain why something is done, not what it does.
22. Reading and Writing Files
Ruby makes it straightforward to read from and write to files — essential for working with logs, configuration, data exports, and persistent storage.
Reading a File
# Read entire file as a string
File.open("employees.txt", "r") do |file|
puts file.read
end
# Read line by line
File.open("employees.txt", "r") do |file|
file.readlines.each do |line|
puts line
end
end
File Modes
| Mode | Description |
|---|---|
"r" | Read-only. Starts at beginning. File must exist. |
"w" | Write-only. Creates new file or truncates existing. |
"a" | Append. Writes only to end of file. Creates if not exists. |
"r+" | Read and write. File must exist. |
"w+" | Read and write. Truncates existing file. |
Writing and Appending to a File
# Append a new line
File.open("employees.txt", "a") do |file|
file.write("\nOscar | Accounting")
end
# Overwrite a file
File.open("report.txt", "w") do |file|
file.write("Monthly Report\n")
file.write("Total Sales: $12,000")
end
# Create a new file
File.open("index.html", "w") do |file|
file.write("<h1>Hello from Ruby!</h1>")
end
23. Exception Handling
Exceptions are runtime errors that crash your program if not handled. Ruby's begin/rescue/end blocks let you catch exceptions gracefully so your program can continue running or fail with a helpful message.
Basic Exception Handling
begin
result = 10 / 0 # Raises ZeroDivisionError
rescue
puts "An error occurred!"
end
Handling Specific Error Types
begin
lucky_nums = [4, 8, 15, 16, 23]
puts lucky_nums["dog"] # TypeError
rescue ZeroDivisionError
puts "Cannot divide by zero"
rescue TypeError => e
puts "Type error: #{e}"
end
Using ensure (Always Runs)
begin
file = File.open("data.txt", "r")
puts file.read
rescue => e
puts "Error reading file: #{e}"
ensure
file.close if file # Always closes the file
end
Common Ruby Exception Types
- ZeroDivisionError — Raised when dividing by zero.
- TypeError — Raised when an operation is applied to an incompatible type.
- NameError — Raised when a variable or method name is not defined.
- NoMethodError — Raised when calling a method that does not exist on an object.
- ArgumentError — Raised when the wrong number or type of arguments is passed.
- RuntimeError — Generic runtime error, the default raised by
raise. - IOError / Errno::ENOENT — Raised for file/IO issues like a missing file.
- IndexError — Raised when an index is out of range for an array.
24. Classes and Objects
Object-Oriented Programming organizes code around objects that represent real-world entities. A class is a blueprint that defines what an object looks like and how it behaves. An object is a specific instance created from that class.
Four Pillars of OOP
- Encapsulation: Bundling data and behavior together inside a class.
- Abstraction: Hiding complex implementation details, exposing only what is necessary.
- Inheritance: A class can inherit attributes and methods from a parent class.
- Polymorphism: Different classes can respond to the same method in different ways.
Creating a Class and Objects
class Book
attr_accessor :title, :author, :pages
def initialize(title, author, pages)
@title = title
@author = author
@pages = pages
end
end
book1 = Book.new("Harry Potter", "J.K. Rowling", 400)
book2 = Book.new("Lord of the Rings", "Tolkien", 500)
puts book1.title # => Harry Potter
puts book2.author # => Tolkien
attr_accessor, attr_reader, attr_writer
- attr_accessor :name — Creates both a getter and setter method.
- attr_reader :name — Creates only a getter. The value cannot be changed from outside.
- attr_writer :name — Creates only a setter. The value cannot be read from outside.
25. The Initialize Method
The initialize method runs automatically every time you create a new object with ClassName.new(). It sets up the initial state. The @ symbol creates instance variables that belong to the specific object and persist across method calls.
class Student
attr_accessor :name, :major, :gpa
def initialize(name, major, gpa)
@name = name
@major = major
@gpa = gpa
end
end
student1 = Student.new("Jim", "Business", 2.6)
student2 = Student.new("Pam", "Art", 3.6)
puts student1.name # => Jim
puts student2.gpa # => 3.6
26. Instance Methods
Instance methods are defined inside a class and operate on a specific object. They can access the object's instance variables using @.
class Student
attr_accessor :name, :major, :gpa
def initialize(name, major, gpa)
@name = name
@major = major
@gpa = gpa
end
def has_honors?
@gpa >= 3.5
end
def to_s
"#{@name} | #{@major} | GPA: #{@gpa}"
end
end
student1 = Student.new("Jim", "Business", 2.6)
student2 = Student.new("Pam", "Art", 3.6)
puts student1.has_honors? # => false
puts student2.has_honors? # => true
puts student2 # => Pam | Art | GPA: 3.6
27. Multiple Choice Quiz Project
This project combines classes, arrays, loops, user input, and conditionals into a complete scored quiz application.
class Question
attr_accessor :prompt, :answer
def initialize(prompt, answer)
@prompt = prompt
@answer = answer
end
end
p1 = "What color are apples?\na) Red b) Purple c) Orange"
p2 = "What color are bananas?\na) Pink b) Red c) Yellow"
p3 = "What color are pears?\na) Orange b) Green c) Blue"
questions = [
Question.new(p1, "a"),
Question.new(p2, "c"),
Question.new(p3, "b")
]
def run_test(questions)
score = 0
questions.each do |q|
puts q.prompt
print "Your answer: "
answer = gets.chomp
score += 1 if answer == q.answer
end
puts "You got #{score} out of #{questions.length} correct."
end
run_test(questions)
28. Inheritance
Inheritance allows a subclass to inherit all methods and attributes from a superclass. The subclass can also override inherited methods or add new ones. Use the < symbol to inherit.
class Chef
def make_chicken
puts "The chef makes chicken"
end
def make_salad
puts "The chef makes salad"
end
def make_special_dish
puts "The chef makes barbecue ribs"
end
end
class ItalianChef < Chef
# Inherits make_chicken and make_salad
# Override the special dish
def make_special_dish
puts "The chef makes eggplant parmigiana"
end
# Add new functionality
def make_pasta
puts "The chef makes fresh pasta"
end
end
chef = Chef.new
italian = ItalianChef.new
chef.make_special_dish # => The chef makes barbecue ribs
italian.make_special_dish # => The chef makes eggplant parmigiana
italian.make_chicken # => The chef makes chicken (inherited)
italian.make_pasta # => The chef makes fresh pasta
29. Modules
A module is a container for grouping related methods. Unlike classes, modules cannot be instantiated. They serve two purposes: namespacing (organizing code) and mixins (sharing behavior across multiple classes without inheritance).
module Tools
def say_hi(name)
puts "Hello, #{name}!"
end
def say_bye(name)
puts "Goodbye, #{name}!"
end
end
class Person
include Tools
end
p = Person.new
p.say_hi("Alice") # => Hello, Alice!
p.say_bye("Alice") # => Goodbye, Alice!
Module vs Inheritance
- Use inheritance when there is a clear "is-a" relationship (an ItalianChef IS-A Chef).
- Use modules when you want to share behavior across unrelated classes (mixins).
- A class can only inherit from one superclass but can include multiple modules.
- Ruby's
ComparableandEnumerablemodules are famous examples of powerful mixins.
Congratulations! You have completed the full Ruby Programming Guide. You now have a solid foundation in Ruby — from installation to object-oriented programming. The next step is to build real projects: a web scraper, a command-line tool, or a Rails application. Keep coding, stay curious, and enjoy the Ruby community.
0 Comments