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

  1. What is Ruby?
  2. Advantages and Disadvantages of Ruby
  3. Installing Ruby — Windows, macOS, Linux, Termux (32-bit and 64-bit)
  4. Setting Up a Text Editor
  5. Your First Ruby Program
  6. Print Statements: puts vs print
  7. Variables
  8. Data Types
  9. Working with Strings
  10. Working with Numbers
  11. Getting User Input
  12. Building a Calculator
  13. Mad Libs Game
  14. Arrays
  15. Hashes
  16. Methods and Return Values
  17. If Statements and Comparisons
  18. Case Expressions
  19. While Loops and the Guessing Game
  20. For Loops and the Exponent Method
  21. Comments
  22. Reading and Writing Files
  23. Exception Handling
  24. Classes and Objects
  25. The Initialize Method
  26. Instance Methods
  27. Multiple Choice Quiz Project
  28. Inheritance
  29. 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

AdvantageDetails
Beginner-FriendlyRuby’s clean, English-like syntax minimizes boilerplate, making it one of the best first languages.
Rapid DevelopmentFewer lines of code compared to Java or C++. Developers build features faster.
Everything is an ObjectConsistent OOP model. Methods can be called on literally any value, including integers and nil.
Strong CommunityLarge, welcoming community with extensive tutorials, gems, and open-source projects.
Ruby on RailsRails remains one of the most productive web frameworks ever built, with massive adoption.
Open SourceCompletely free to use, modify, and distribute. No licensing fees.
MetaprogrammingRuby allows programs to write and modify code at runtime — powerful for DSLs and frameworks.
Gems EcosystemRubyGems provides access to over 170,000 libraries covering almost any task imaginable.
Cross-PlatformRuns on Windows, macOS, Linux, and even mobile environments like Termux.
Great for PrototypingIdeas can be turned into working code quickly, making Ruby ideal for MVPs and hackathons.

Disadvantages

DisadvantageDetails
PerformanceRuby is slower than compiled languages like C, Java, or Go. Not ideal for CPU-intensive tasks.
ConcurrencyThe Global Interpreter Lock (GIL) in MRI Ruby limits true parallel threading.
Runtime ErrorsDynamic typing means type errors only surface at runtime, not compile time.
Memory UsageRuby applications tend to use more memory compared to languages like Go or Rust.
Boot TimeRails applications can be slow to start up, making development feedback loops longer.
Mobile DevelopmentLimited native mobile support compared to Swift (iOS) or Kotlin (Android).
Job Market ShiftWhile still in demand, Python and JavaScript have overtaken Ruby in raw job postings.
Debugging ComplexityDynamic 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.


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

print

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: age and Age are different variables.
  • Names should be descriptive — character_name is better than cn.
  • 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.

TypeDescriptionExample
StringPlain text, enclosed in quotes."Hello, Ruby!"
IntegerWhole numbers, positive or negative.42, -7, 0
FloatDecimal/floating point numbers.3.14, -0.5
BooleanTrue or false values only.true, false
NilRepresents the absence of a value.nil
SymbolImmutable identifier, like a named constant.:name, :status
ArrayOrdered list of values.[1, "a", true]
HashKey-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

OperatorMeaningExample
==Equal to5 == 5 # true
!=Not equal to5 != 3 # true
>Greater than7 > 3 # true
<Less than2 < 9 # true
>=Greater than or equal5 >= 5 # true
<=Less than or equal3 <= 4 # true
&&Logical ANDtrue && false # false
||Logical ORtrue || 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

ModeDescription
"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 Comparable and Enumerable modules 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

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *