while, until and loop
Bean Cart's espresso machine needs to heat up before the first order: keep checking the temperature until it reaches 93 degrees. You do not know in advance how many checks that takes. When a loop depends on a condition rather than a count, Ruby reaches for while, until and loop.
The rule
whileruns as long as true;untilruns as long as false.
A while loop checks its condition before each pass and stops the first time it is falsy:
temp = 20
while temp < 93
temp += 25
puts "Heating... #{temp}"
end
# Heating... 45, Heating... 70, Heating... 95until is the mirror image, exactly as unless mirrors if. It keeps going while the condition is falsy and stops once it becomes true:
temp = 20
until temp >= 93
temp += 25
endBoth have a one-line modifier form: temp += 25 while temp < 93.
Because the condition is checked first, the body may run zero times: with temp = 95, neither loop above runs at all.
Sometimes you need the body to run at least once, the classic "do/while". Ruby can write it by putting while after a begin ... end block:
begin
reading = sensor_temperature
end while reading < 93This form checks the condition after each pass. It works, but Ruby's creator has advised against it because it behaves differently from the modifier form, and style guides agree. The clearer Ruby idiom is loop with break:
loop do
reading = sensor_temperature
break if reading >= 93
endloop do ... end repeats forever until something inside stops it, which makes the exit condition sit exactly where it is checked.
Whatever you choose, make sure the body changes something the condition depends on. If temp never changes, while temp < 93 never ends. Press Ctrl+C to stop a runaway loop in the terminal.
The shortcut
Say the stopping rule out loud. If it sounds like "keep going while ...", use while. If it sounds like "keep going until ...", use until. If the body must run before you can even test, use loop with break if.
Say the rule
"Keep heating until it reaches 93." That is an until sentence.
Drills
Answer fast — trust the rule.
When does until done stop looping?
With n = 10, how many times does the body of while n < 5 run?
Which loop checks its condition after the body, so the body always runs at least once?
What does the recommended Ruby idiom for "run at least once" look like?
With cups = 0, what is cups after cups += 4 until cups > 10?
Remember
whileruns as long as true;untilruns as long as false. Both test before each pass.- Say the stopping rule out loud to choose; use
loopwithbreak iffor "at least once". - Trap: a condition the body never changes, which loops forever.
