Conditional Statements in Ruby
Crucial control flow techniques in Ruby, conditional statements let your program to decide what to do and run different code blocks depending on predetermined criteria. Conditionals are technically expressions that evaluate to a value, as are almost all other control structures in Ruby.
The Foundation of Conditionals: Truthiness and Falsiness
A Ruby condition is satisfied if the expression being tested is “truthy.” In contrast to languages like JavaScript or C Language, Ruby has a very rigid notion of what is not true:
Falsy Values: Two values in particular are deemed “false” (will yield false when evaluated as a condition):
false
.nil
.
Truthy Values: Each other value is regarded as “truthy” (will, when tested as a condition, return true). In other languages, these values are frequently regarded as incorrect:
- The numeric zero (
0
). - The empty string (
""
). - Empty arrays (
[]
). - Empty hashes (
{}
).
You can use the double negation syntax (!!) to explicitly examine a value’s boolean status.
Code Example (Testing Truthiness):
def check_truthy(var_name, var)
is_truthy = var ? "truthy" : "falsy"
puts "#{var_name} is #{is_truthy}"
end
check_truthy("false", false) # => false is falsy
check_truthy("nil", nil) # => nil is falsy
check_truthy("0", 0) # => 0 is truthy
check_truthy("empty string", "") # => empty string is truthy
Output
false is falsy
nil is falsy
0 is truthy
empty string is truthy
if
statement
For conditional branching, the most common form is the if statement.
Structure and Syntax
The if keyword is used to begin the if expression, which needs to be ended. Either a newline, a semicolon (;), or the keyword then must be used to separate the condition from the code block. The term “condition” is usually not included in parenthesis.
elsif
: Allows for additional condition checks. Note the spelling with only one ‘e’.else
: Contains the code that runs if all precedingif
andelsif
conditions evaluate tofalse
ornil
.
Code Example (Standard Branching):
x = 2
if x == 1
puts "one"
elsif x == 2
puts "two"
else
puts "many"
end
Output
two
if
as an Expression
An expression that returns the value of the last statement run in the corresponding block, or nil if no block was run, is what Ruby’s if structure is all about. This enables a variable to be immediately assigned to the result.
Code Example (Assignment using if expression):
age = 25
status = if age < 18
:minor
else
:adult
end
# This line explicitly prints the value of the `status` variable.
puts "The person's status is: #{status}"
Output
The person's status is: adult
unless
statement
The except statement is a negated version of if that only runs code in the event that the condition is nil or false. When employing a negative expression, it is advised because it makes the code easier to read.
The else clause, which runs if the condition is true, is supported by the except statement, but the elsif clause is not.
Code Example (Using unless):
document_read_only = false
unless document_read_only
puts "Document is editable."
else
puts "Document is read-only."
end
# => Document is editable.
Output
Document is editable.
Conditional Modifiers (Inline)
When used as modifiers for straightforward, one-line assertions, if, except, while, and until should be placed right after the expression they change. This format highlights the code that is being run.
For if/while, the changed phrase is evaluated only if the condition is met; for unless/until, it is assessed for unmet conditions.
Constraint: You can’t use an else clause in modifier form.
Precedence: Since they bind weakly, modifiers have relatively little precedence.
Code Example (Conditional Modifiers):
radiation = 4000
# Prints a warning if the condition is true
puts "Danger, Will Robinson" if radiation > 3000
Output
Danger, Will Robinson
The Ternary Operator ()
Ruby has only one ternary (three-operand) operator, the conditional operator (?:). It offers a condensed substitute for an if/else statement.
Syntax
The format is conditional ? value_if_truthy : value_if_falsy
.
Code Example (Ternary Operator):
# Assign a value to the 'age' variable.
age = 25
# Use a ternary operator to assign a status based on age.
# If age is less than 18, 'status' will be :minor.
# Otherwise, 'status' will be :adult.
status = age < 18 ? :minor : :adult
# Print the final value of the 'status' variable to the console.
puts status
Output
adult
case
statement
One multiway conditional structure that is useful is the case statement. After the case keyword, an optional phrase can be entered, and it will be compared to several when clauses.
Matching Mechanism ()
Instead of the ordinary == operator, the case equality operator (===) is the central component of the case statement. If the left operand (the value of the when expression) subsumes the right operand (the value of the case expression), then the === operator checks.
To offer semantic matching, classes frequently override this operator:
Ranges: uses Range#include?
to determine whether a value is part of the range.
Regular Expressions: determines if a string fits the regexp#=~
pattern.
Classes/Modules: Verifies whether the value belongs to the class (Module#is_a?
).
The first matching when block’s statements are performed if the case condition is true. Clauses such as “never allows fall-through” or “no break is required” are verified only after a match has been found.
Code Example (Case with Type and Range Matching):
x = 17
case x
when 13..19 # Matches against Range
puts "teenager"
when Integer # Matches against Class
puts "It's an integer"
when /foo/ # This branch is skipped
puts "Contains 'foo'"
else
puts "Other"
end
Output
teenager
Code Example (Case without an explicit subject):
You can use a case statement without a subject (the phrase that comes after the case). This version tests each when clause independently as a boolean condition until one of them evaluates to true.
case
when ENV['A'] == 'Y'
puts 'A'
when ENV['B'] == 'Y'
puts 'B'
else
puts 'Neither A nor B'
end
Output
Neither A nor B
Related Control Flow Structures
Loops
A section of code can be continually run using while loops.
while
: carries out the block while the condition is true.until
: carries out the block until the condition is met (i.e., while it is false).
Code Example (Looping):
i = 0
until i == 5
puts "Iteration ##{i}"
i +=1
end
# Executes 5 times
Output
Iteration #0
Iteration #1
Iteration #2
Iteration #3
Iteration #4
The Flip-Flop Operator
The flip-flop operator is employed in a conditional or loop statement between two conditions. It evaluates to false until the left operand, the first condition, turns true, at which time it “flips” to true. It remains true until the right operand, the second condition, becomes true, after which it “flops” back to false.
Code Example (Flip-Flop):
result = (1..5).select do |e|
e >= 2 && e <= 4
end
puts result
Output
2
3
4
Exception Handling Conditionals
To regulate flow based on success or failure, the keywords else and assure are also utilised in exception handling (begin/rescue blocks).
rescue
: If an exception is raised in the begin block, control is transferred.
else
(in exception handling): The otherwise clause’s code is only executed if the begin block’s function is completed without raising an exception.
ensure
: Includes code that is always run when the block ends, whether a return was sent, an exception was raised, or the block ended normally.
Code Example (Exception else and ensure):
def example_division(x, y)
begin
z = x/y
rescue ZeroDivisionError
puts "Don't divide by zero!"
return nil
else
puts "This code runs on success."
return z
ensure
puts "This code ALWAYS runs."
end
end
example_division(10, 2)
# => This code runs on success.
# => This code ALWAYS runs.
# => 5 [119, 127]
example_division(10, 0)
# => Don't divide by zero!
# => This code ALWAYS runs.
# => nil
Output
This code runs on success.
This code ALWAYS runs.
Don't divide by zero!
This code ALWAYS runs.
You can also read What Is Mean By Operators In Ruby, It’s Types With Examples