Loops in Ruby
Ruby gives you several ways to repeat a block of code, but the language's philosophy nudges you away from the classic C-style loop counter and toward expressive, object-oriented iteration. You'll find while and until for condition-driven repetition, loop for infinite loops with explicit break conditions, and the for keyword, which exists mostly for familiarity but is rarely used idiomatically. Once you reach the Enumerable methods like times, each, and upto, you're writing Ruby the way experienced Rubyists do — treating iteration as a message sent to an object rather than a manual counter you manage yourself.
Cricket analogy: Ruby nudging you toward each over a manual counter is like a captain trusting a bowler to manage their own over rather than micromanaging every single ball's line and length from the boundary.
while, until, and loop
while runs its body as long as a condition is truthy; until is its mirror image, running as long as a condition is falsy. Both support a single-line modifier form, and begin...end while condition is a post-condition variant that guarantees the body executes at least once, similar to a do...while loop in C-family languages. For cases where the natural exit point sits in the middle of the logic rather than at a header, loop do ... end runs indefinitely until an explicit break — and break value can return that value from the loop expression itself, while next skips ahead to the following iteration, mirroring continue in other languages.
Cricket analogy: while running as long as a condition is truthy is like a batting partnership continuing while the required run rate is achievable, and begin...end while guaranteeing one execution is like facing at least one ball before rain can stop play.
count = 0
while count < 5
puts "count is #{count}"
count += 1
end
# modifier form
count += 1 while count < 10
# begin/end while guarantees at least one execution
begin
puts "runs once even if false"
end while falseresult = loop do
line = gets
break "end of input" if line.nil?
next if line.strip.empty?
puts line.upcase
endIterating without manual counters
Rather than manually incrementing a counter, Ruby encourages you to ask a number, range, or collection to iterate itself. 5.times { ... }, (1..5).each { ... }, and 1.upto(5) { ... } all express intent more clearly than a raw while loop and eliminate off-by-one errors because the boundary logic lives inside the method, not your code. Calling any of these iterators without a block returns an Enumerator object instead of running immediately, which lets you store the iteration plan, chain further Enumerable methods, or hand it a block later.
Cricket analogy: 5.times { ... } asking a number to iterate itself is like a bowler being told 'bowl your over' rather than the umpire manually counting each of the six balls aloud, the boundary logic living inside the over itself.
5.times { |i| puts "iteration #{i}" }
(1..5).each { |n| puts n * n }
1.upto(5) { |n| print "#{n} " }
5.downto(1) { |n| print "#{n} " }
# without a block, an iterator returns an Enumerator
enum = (1..5).each
enum.next # => 1Unlike Python, which has no C-style for (init; cond; incr) loop at all, Ruby technically has for item in collection — but idiomatic Ruby avoids it because it doesn't create a new scope for its loop variable (it leaks into the enclosing scope) and because each reads more naturally as "send each element a block" rather than "iterate a collection."
while/untilrepeat based on a condition checked before each iteration; both support a single-line modifier form.begin...end while conditionguarantees the body runs at least once, unlike a standardwhileloop.loop do ... endruns indefinitely until an explicitbreak, which can also return a value from the loop.nextskips to the next iteration;breakexits the loop entirely.- Idiomatic Ruby favors
times,each,upto/downto, andstepover manual counters or theforkeyword. - Calling an iterator without a block returns an Enumerator, enabling lazy chaining and composition.
Practice what you learned
1. Which loop construct in Ruby guarantees its body executes at least once?
2. What does `break` do inside a `loop do ... end` block?
3. Why is `for item in collection` considered less idiomatic than `collection.each`?
4. What does `next` do inside an iteration block?
5. What is returned when you call `(1..5).each` without a block?
Was this page helpful?
You May Also Like
Conditional Statements in Ruby
How to control program flow in Ruby with if/elsif/else, unless, ternary expressions, and modifier conditionals, plus Ruby's truthiness rules.
each, map, and select
Master the three most commonly used Enumerable methods — each for side effects, map for transformation, and select for filtering — and when to reach for which.
Enumerable Deep Dive
Go beyond map and select to explore Enumerable's full toolkit — sort_by, group_by, partition, each_with_object, lazy enumerators, and more — for expressive collection processing.
Case Expressions
How Ruby's case/when expression uses the triple-equals operator for flexible pattern matching against classes, ranges, regexes, and values.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics