Ruby Conditional Statements
Conditional statements are fundamental control structures in programming, used to execute different code paths based on different conditions. Ruby provides various conditional statements that enable code to make decisions based on runtime situations. This chapter will introduce in detail the various conditional statements in Ruby and how to use them.
🎯 Conditional Statement Basics
Boolean Values and Truthiness
In Ruby, all values except false and nil are considered truthy:
ruby
# Truthy values
puts !!true # true
puts !!1 # true (number)
puts !!"Hello" # true (non-empty string)
puts !![] # true (empty array)
puts !!{} # true (empty hash)
puts !!0 # true (zero is also truthy!)
# Falsy values
puts !!false # false
puts !!nil # falseConditional Expressions
ruby
# Basic comparison
puts 5 > 3 # true
puts 5 == 5 # true
puts "apple" < "banana" # true
# Complex conditions
age = 25
has_license = true
if age >= 18 && has_license
puts "Can drive"
end
# String and number comparison
puts "10" == 10 # false (different types)
puts "10" == "10" # true
puts 10 == 10 # true🔀 if Statements
Basic if Statements
ruby
# Simple conditional check
age = 18
if age >= 18
puts "You are an adult"
end
# if-else statement
if age >= 18
puts "Adult"
else
puts "Minor"
end
# if-elsif-else statement
if age < 13
puts "Child"
elsif age < 18
puts "Teenager"
elsif age < 60
puts "Adult"
else
puts "Senior"
endSingle-Line if Statements
ruby
# Modifier form of if statement
puts "Adult" if age >= 18
name = "Zhang San"
puts "Welcome, #{name}!" if name
# Multiple conditions
score = 85
puts "Excellent" if score >= 90
puts "Good" if score >= 80 && score < 90
puts "Pass" if score >= 60 && score < 80if Statement Return Values
ruby
# if statements have return values
result = if age >= 18
"Adult"
else
"Minor"
end
puts result # Adult
# More complex return values
grade = 85
level = if grade >= 90
"Excellent"
elsif grade >= 80
"Good"
elsif grade >= 60
"Pass"
else
"Fail"
end
puts level # Good🔁 unless Statements
Basic unless Statements
ruby
# unless is equivalent to if not
age = 16
unless age >= 18
puts "Minor"
end
# unless-else statement
unless age >= 18
puts "Minor"
else
puts "Adult"
end
# Single-line unless statement
puts "Minor" unless age >= 18unless Usage Scenarios
ruby
# Suitable for negative condition checks
user = nil
puts "Please log in first" unless user
file_exists = File.exist?("config.txt")
puts "Configuration file does not exist" unless file_exists
# Avoid double negation
# Not recommended: if !user.nil?
# Recommended: unless user.nil? or more concise: if user🔄 case Statements
Basic case Statements
ruby
# Simple case statement
grade = "B"
case grade
when "A"
puts "Excellent"
when "B"
puts "Good"
when "C"
puts "Pass"
else
puts "Fail"
end
# case statement return value
score = 85
level = case score
when 90..100
"Excellent"
when 80...90
"Good"
when 60...80
"Pass"
else
"Fail"
end
puts level # GoodMultiple Value Matching
ruby
# One when clause matching multiple values
day = "Saturday"
case day
when "Saturday", "Sunday"
puts "Weekend"
when "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"
puts "Weekday"
end
# Using arrays for matching
weekend_days = ["Saturday", "Sunday"]
work_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
case day
when *weekend_days
puts "Weekend"
when *work_days
puts "Weekday"
endRange Matching
ruby
# Use ranges for matching
score = 85
case score
when 90..100
puts "Excellent"
when 80...90
puts "Good"
when 70...80
puts "Average"
when 60...70
puts "Pass"
else
puts "Fail"
endRegular Expression Matching
ruby
# Use regular expressions for matching
email = "user@example.com"
case email
when /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
puts "Valid email address"
when /\A\d{11}\z/
puts "Possible phone number"
else
puts "Unknown format"
endHow case Statements Work
ruby
# case uses === operator for comparison
# Different types of objects have different === implementations
# Number comparison
case 5
when 1..10
puts "Between 1 and 10"
end
# Type checking
case "Hello"
when String
puts "This is a string"
when Numeric
puts "This is a number"
end
# Custom class === method
class Priority
def self.===(value)
value.is_a?(Integer) && value > 100
end
end
case 150
when Priority
puts "High priority"
else
puts "Normal priority"
end🎯 Ternary Operators
Basic Syntax
ruby
# Ternary operator: condition ? value_if_true : value_if_false
age = 20
status = age >= 18 ? "Adult" : "Minor"
puts status # Adult
# Nested ternary operators (use with caution)
score = 85
grade = score >= 90 ? "Excellent" :
score >= 80 ? "Good" :
score >= 60 ? "Pass" : "Fail"
puts grade # GoodTernary Operator Application Scenarios
ruby
# Simple conditional assignment
user = nil
display_name = user ? user.name : "Anonymous User"
# Or use more concise form
display_name = user&.name || "Anonymous User"
# Conditional output
debug_mode = true
puts "Debug info" if debug_mode
# Conditional method calls
class Calculator
def initialize(debug = false)
@debug = debug
end
def add(a, b)
result = a + b
puts "Calculation: #{a} + #{b} = #{result}" if @debug
result
end
end🔄 Modifier Forms
if and unless Modifiers
ruby
# if modifier
puts "Adult" if age >= 18
raise "Invalid age" if age < 0
return unless user
# unless modifier
puts "Please log in" unless user
exit unless ready?
# Multiple modifier combinations
puts "Adult and logged in" if age >= 18 && user
puts "Minor or not logged in" unless age >= 18 && userwhile and until Modifiers
ruby
# while modifier
counter = 0
counter += 1 while counter < 5
puts counter # 5
# until modifier
counter = 5
counter -= 1 until counter <= 0
puts counter # 0🎯 Complex Conditional Judgments
Logical Operator Combinations
ruby
# AND operations (&&)
user = {name: "Zhang San", age: 25, active: true}
if user[:age] >= 18 && user[:active]
puts "#{user[:name]} can access"
end
# OR operations (||)
role = "admin"
if role == "admin" || role == "moderator"
puts "Has admin permissions"
end
# NOT operations (!)
logged_in = false
puts "Please log in" if !logged_in
# Complex condition combinations
if (user[:age] >= 18 && user[:active]) || user[:role] == "admin"
puts "Access granted"
endShort-Circuit Evaluation
ruby
# && short-circuit: If left is false, don't evaluate right
def expensive_check
puts "Executing expensive check"
true
end
false && expensive_check # Won't output "Executing expensive check"
# || short-circuit: If left is true, don't evaluate right
true || expensive_check # Won't output "Executing expensive check"
# Use short-circuit evaluation for safe access
user = nil
# Safely access nested attributes
name = user && user.profile && user.profile.name
# Or use safe navigation operator (Ruby 2.3+)
name = user&.profile&.nameConditional Assignment
ruby
# ||= Conditional assignment
cache = nil
cache ||= expensive_computation # First computation executed
cache ||= another_computation # Won't execute, uses cached value
# &&= Conditional assignment
value = 10
value &&= value * 2 # value = 20
value = nil
value &&= value * 2 # value remains nil🧪 Conditional Statement Practice Examples
User Permission Check System
ruby
class PermissionChecker
def initialize(user)
@user = user
end
def can_access?(resource)
# Admins can access all resources
return true if admin?
# Check specific permissions
case resource
when :public
true
when :private
logged_in?
when :admin_only
admin?
when :premium
premium_user?
else
false
end
end
def check_access(resource)
if can_access?(resource)
puts "Access granted: #{resource}"
true
else
puts "Access denied: #{resource}"
false
end
end
private
def logged_in?
!@user.nil?
end
def admin?
@user && @user[:role] == :admin
end
def premium_user?
@user && (@user[:role] == :premium || @user[:role] == :admin)
end
end
# Use permission check system
users = [
nil, # Not logged in user
{name: "Regular User", role: :user},
{name: "Premium User", role: :premium},
{name: "Admin", role: :admin}
]
resources = [:public, :private, :premium, :admin_only]
checker = PermissionChecker.new(nil)
users.each do |user|
checker.instance_variable_set(:@user, user)
user_name = user ? user[:name] : "Guest"
puts "\n=== #{user_name} ==="
resources.each do |resource|
checker.check_access(resource)
end
endScore Grade Evaluation System
ruby
class GradeEvaluator
def self.evaluate(score)
case score
when 90..100
"Excellent"
when 80...90
"Good"
when 70...80
"Average"
when 60...70
"Pass"
when 0...60
"Fail"
else
raise ArgumentError, "Invalid score: #{score}"
end
end
def self.detailed_evaluate(score)
grade = evaluate(score)
description = case grade
when "Excellent"
"Excellent performance, keep it up"
when "Good"
"Good performance, room for improvement"
when "Average"
"Meets basic requirements, needs effort"
when "Pass"
"Just passed, need to strengthen study"
when "Fail"
"Does not meet requirements, need to retake"
end
{
grade: grade,
score: score,
description: description
}
end
def self.batch_evaluate(scores)
results = []
scores.each_with_index do |score, index|
begin
result = detailed_evaluate(score)
result[:student_id] = index + 1
results << result
rescue ArgumentError => e
results << {
student_id: index + 1,
error: e.message
}
end
end
results
end
end
# Use grade evaluation system
scores = [95, 87, 76, 65, 45, 105, -5]
results = GradeEvaluator.batch_evaluate(scores)
results.each do |result|
if result[:error]
puts "Student #{result[:student_id]}: #{result[:error]}"
else
puts "Student #{result[:student_id]}: #{result[:score]} points - #{result[:grade]} - #{result[:description]}"
end
endConfiguration File Parser
ruby
class ConfigParser
def self.parse(config)
parsed = {}
config.each do |key, value|
parsed[key] = parse_value(key, value)
end
parsed
end
private
def self.parse_value(key, value)
case key.to_s
when /_enabled$/, /_active$/
parse_boolean(value)
when /_count$/, /_size$/, /_limit$/
parse_integer(value)
when /_timeout$/, /_delay$/
parse_float(value)
when /_list$/, /_array$/
parse_array(value)
when /_path$/
parse_path(value)
else
value # Keep original value
end
end
def self.parse_boolean(value)
case value
when true, false
value
when String
case value.downcase
when "true", "1", "yes", "on"
true
when "false", "0", "no", "off"
false
else
raise ArgumentError, "Invalid boolean value: #{value}"
end
when Numeric
value != 0
else
!!value
end
end
def self.parse_integer(value)
case value
when Integer
value
when String
Integer(value)
when Float
value.to_i
else
raise ArgumentError, "Invalid integer value: #{value}"
end
rescue ArgumentError
raise ArgumentError, "Invalid integer value: #{value}"
end
def self.parse_float(value)
case value
when Float, Integer
value.to_f
when String
Float(value)
else
raise ArgumentError, "Invalid float value: #{value}"
end
rescue ArgumentError
raise ArgumentError, "Invalid float value: #{value}"
end
def self.parse_array(value)
case value
when Array
value
when String
value.split(",").map(&:strip)
else
[value]
end
end
def self.parse_path(value)
case value
when String
# Simple path cleanup
value.gsub(/[<>:"|?*]/, "") # Remove illegal characters
else
value.to_s
end
end
end
# Use configuration parser
config = {
debug_enabled: "true",
max_connections: "100",
request_timeout: "30.5",
allowed_hosts: "localhost,127.0.0.1,example.com",
log_path: "/var/log/app.log",
cache_size: 1024
}
begin
parsed_config = ConfigParser.parse(config)
parsed_config.each do |key, value|
puts "#{key}: #{value} (#{value.class})"
end
rescue ArgumentError => e
puts "Configuration parse error: #{e.message}"
end🎯 Conditional Statement Best Practices
1. Keep Conditions Simple
ruby
# Good practice: Extract complex conditions into methods
class UserValidator
def self.valid_user?(user)
user &&
user.active? &&
user.email_verified? &&
user.age >= 18
end
def self.premium_user?(user)
valid_user?(user) && user.subscription == "premium"
end
end
# Use
if UserValidator.premium_user?(user)
# Handle premium user
end2. Use case Statements Reasonably
ruby
# Good practice: Use case for multiple discrete values
case action
when "create"
create_resource
when "update"
update_resource
when "delete"
delete_resource
else
raise ArgumentError, "Unknown action: #{action}"
end
# Avoid: Using case for simple conditions
# Not recommended:
case
when score >= 90
puts "Excellent"
when score >= 80
puts "Good"
end
# Recommended:
if score >= 90
puts "Excellent"
elsif score >= 80
puts "Good"
end3. Avoid Deep Nesting
ruby
# Bad practice: Deep nesting
if user
if user.active?
if user.age >= 18
if user.subscription == "premium"
# Processing logic
end
end
end
end
# Good practice: Early returns
def process_user(user)
return unless user
return unless user.active?
return unless user.age >= 18
return unless user.subscription == "premium"
# Processing logic
end
# Or merge conditions
def process_user(user)
if user && user.active? && user.age >= 18 && user.subscription == "premium"
# Processing logic
end
end4. Use Safe Navigation Operators
ruby
# Old way: Multiple nil checks
if user && user.profile && user.profile.address && user.profile.address.city
puts user.profile.address.city
end
# New way: Safe navigation operator (Ruby 2.3+)
puts user&.profile&.address&.city
# Combine with conditional assignment
city = user&.profile&.address&.city || "Unknown City"📚 Next Steps
After mastering Ruby conditional statements, it is recommended to continue learning:
- Ruby Loops - Learn various loop control structures
- Ruby Control Structures - Master more advanced control flow
- Ruby Exception Handling - Learn error handling mechanisms
- Ruby Pattern Matching - Learn modern Ruby's pattern matching features
Continue your Ruby learning journey!