Ruby
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Methods and Blocks
-
Section 4: Object-Oriented Ruby
-
Section 5: Metaprogramming
-
Section 6: Working with Data and Files
-
Section 7: Ruby Frameworks Overview
-
Section 8: Ecosystem and Testing
-
Section 9: Practical Projects
-
Section 10: Interview Practice
-
Section 11: Data Structures and Algorithms in Ruby
-
Section 12: More Practice Exercises
-
Section 13: Enumerable and Functional Style
-
Section 14: More OOP Practice
-
Section 15: More Testing
-
Section 16: Enumerable and Comparable Modules In Depth
-
Section 17: Ruby Standard Library: Core Utilities
-
Section 18: Ruby Standard Library: Data and Security
-
Section 19: Ruby Standard Library: CLI and Text
-
Section 20: Ruby Networking
-
Section 21: Ruby on Rails Deep Dive
-
Section 22: Ruby Metaprogramming Deep Dive
-
Section 23: Ruby Design Patterns
-
Section 24: Ruby Concurrency
-
Section 25: Ruby Testing Deep Dive
-
Section 26: Ruby Gems and Packaging
-
Section 27: Ruby Performance
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Rails API Development
-
Section 31: Rails Authentication and Authorization
-
Section 32: Rails Testing Deep Dive
-
Section 33: Rails Performance
-
Section 34: Rails Deployment
-
Section 35: Sinatra and Lightweight Ruby Web Apps
-
Section 36: More Ruby Language Deep Dive
-
Section 37: Ruby 3.x Modern Features
-
Section 38: More Data Structures in Ruby
-
Section 39: More Practical Projects
-
Section 40: Ruby Ecosystem Tools
-
Section 41: More Practice and Review
-
Section 42: Final Practice and Mastery
-
Section 43: Ruby Interview Deep Dive
-
Section 44: Ruby Background Processing Deep Dive
-
Section 45: Ruby GraphQL
-
Section 46: Ruby Object Model Deep Dive
-
Section 47: Ruby Hanami Framework Overview
-
Section 48: Ruby gRPC and Protocol Buffers
-
Section 49: Ruby Data Processing
-
Section 50: Ruby Search Integration
-
Section 51: Ruby File Upload and Media
-
Section 52: Ruby Email and Notifications
-
Section 53: Ruby Admin Panels
-
Section 54: Ruby Feature Flags and Experimentation
-
Section 55: Ruby Monitoring and Observability
-
Section 56: Ruby Docker and Deployment Deep Dive
-
Section 57: Ruby Security Deep Dive
-
Section 58: More Advanced Metaprogramming
-
Section 59: More Final Projects
5: Control Flow Statements
Think of control flow like a road trip with a GPS. Most of the time, you're just driving straight. But every so often, you hit a fork in the road. Your GPS tells you, "If the highway is congested, take the side road; otherwise, stay on the I-95." Or maybe you have a checklist of stops: "For every city on this list, find a local coffee shop." Control flow is simply the way we tell Ruby to stop moving in a straight line and start making decisions or repeating actions based on the current situation.
Here is how that road trip maps to the code we're about to write:
- The Fork in the Road: This is your
ifandelse. It's a binary choice based on a condition. - The "Only If Not" Rule: This is
unless. It's like saying, "I'll keep driving unless I run out of gas." - The Multi-Stop Itinerary: This is the
casestatement. Instead of a simple yes/no, you're choosing one path from several distinct options. - The Checklist: These are your loops and iterators. You perform the same action over and over until you've hit every item on your list.
Making decisions with if and else
In Ruby, if statements are the bread and butter of your logic. I've found that the biggest mistake beginners make is over-complicating the condition. Keep it simple. Let's imagine we're building a system to determine ticket prices for a cinema.
age = 15
if age < 12
puts "Child ticket: $5"
elsif age < 65
puts "Adult ticket: $12"
else
puts "Senior ticket: $7"
end
Notice the elsif (no 'e' at the end)—that's a Ruby-ism. The code reads almost like a sentence. Once Ruby finds a condition that is true, it executes that block and skips the rest. It doesn't keep checking the other options once it's found a match.
The Ruby-esque 'unless'
You'll see unless a lot in professional Ruby codebases. It's essentially the opposite of if. It runs the code only if the condition is false. I personally use it when I want to handle "guard clauses"—checking for a reason to stop before the main logic happens.
is_member = false
unless is_member
puts "Please sign up for a membership to get the discount!"
end
You could write this as if !is_member, but that's clunky. unless makes the intention clear: "Do this, unless this specific thing is true."
Choosing from a menu with case
When you have four or five different options, a long chain of elsif statements becomes a nightmare to read. That's where case comes in. It's much cleaner when you're comparing one value against multiple possibilities.
movie_genre = "Sci-Fi"
case movie_genre
when "Horror"
puts "Dim the lights and grab a blanket."
when "Comedy"
puts "Get the popcorn and get ready to laugh."
when "Sci-Fi"
puts "Prepare for interstellar travel."
else
puts "Just enjoy the movie!"
end
Repeating yourself (efficiently)
While Ruby has while and until loops, you'll rarely see them in modern Ruby projects. We prefer iterators. Instead of managing a counter variable manually, we tell Ruby to "do this for each item in this collection."
snacks = ["Popcorn", "Nachos", "Candy", "Pretzels"]
snacks.each do |snack|
puts "Now serving: #{snack}"
end
The |snack| part is what we call a block variable. For every lap around the loop, Ruby grabs the next item from the array and plugs it into that variable. It's cleaner, less prone to "off-by-one" errors, and frankly, just more pleasant to read.
📋 Practical Task
Build a Movie Theater Admission Guard
You need to write a small program that determines if a customer can enter a movie and what they have to pay. Create a script that uses the following logic:
- Create a variable for
ageand a variable forhas_ticket(boolean). - First, use an
unlessstatement to check if they have a ticket. If they don't, print "Please purchase a ticket first." - If they do have a ticket, use an
if/elsif/elseblock to print their pricing:- Under 13: "Child Price"
- 13 to 64: "Adult Price"
- 65 and over: "Senior Price"
- Finally, create an array of
required_items(e.g., ["Ticket", "ID", "Mask"]) and use the.eachiterator to print a checklist of everything the customer needs to show at the door.
There are no comments for now.