Ruby's conditionals are expressions, and its idioms (modifiers, unless, case with ranges) read almost like English.
if/elsif/else/end and unless (the negation of if) work as expected. In Ruby these are expressions: they return the value of the branch taken, so label = if score > 50 then "pass" else "fail" end is valid. The ternary cond ? a : b covers short cases.
Modifier forms put the condition after a single statement: return if list.empty?, retry_later unless connected?. They are idiomatic for guard clauses. Avoid unless with else or with negations; it gets hard to read.
case/when compares using ===, the "case equality" operator, so a when can be a value, a class, a range or a regex:
case input
when Integer then "number"
when 1..5 then "small" # Range#=== checks inclusion
when /\A\d+\z/ then "digits" # Regexp#=== matches
else "other"
endLoops: while cond ... end, until cond ... end and loop do ... end (exit with break). In practice Rubyists rarely write for; they use iterators: 3.times { |i| ... }, 1.upto(5), array.each. Inside blocks and loops, next skips to the next iteration and break exits.
&&, || and ! are the logical operators. The words and, or and not exist but have very low precedence; use them only for control flow like save or raise "failed", never in conditions.
Example
def classify(x)
case x
when Integer then x.negative? ? "negative" : "integer"
when 0.0..1.0 then "fraction"
when /\A\w+@\w+\.\w+\z/ then "email"
when nil then "missing"
else "unknown"
end
end
[5, -2, 0.5, "a@b.io", nil, :x].each { |v| puts classify(v) }
# integer negative fraction email missing unknown (one per line)
grade = if 72 >= 70 then "pass" else "fail" end
puts grade # pass
3.times { |i| print i, " " } # 0 1 2
puts
n = 0
n += 1 until n * n > 50
puts n # 8Remember
- if, unless and case are expressions that return a value
- case/when uses ===, so classes, ranges and regexes all work
- Prefer iterators like times and each over for loops
Watch out for
- Using and/or in assignments: x = true and false sets x to true because = binds tighter.