while / until / loop
Ruby loops: each, times, while, until, loop, and the iterator + block idioms that read like English.
Ruby — loops
EXAMPLE
# ===== each (the canonical iterator) =====
[1, 2, 3].each { |x| puts x }
[1, 2, 3].each do |x|
puts x * x
end
# ===== times =====
5.times { |i| puts "iter #{i}" }
5.times.to_a # [0,1,2,3,4]
# ===== upto / downto / step =====
1.upto(5) { |i| puts i } # 1..5
10.downto(1) { |i| puts i }
0.step(10, 2) { |i| puts i } # 0,2,4,6,8,10
# ===== Range loops =====
(1..10).each { |i| puts i }
(1...10).each { |i| puts i } # exclusive end
('a'..'e').each { |c| puts c } # 'a','b','c','d','e'
# ===== while / until =====
i = 0
while i < 5
puts i
i += 1
end
i = 5
until i.zero?
puts i
i -= 1
end
# Postfix form:
puts 'big' while x > 100
puts 'small' until x > 100
# ===== loop (infinite, break to exit) =====
loop do
line = gets&.chomp
break if line.nil? || line == 'quit'
puts line.upcase
end
# ===== Common patterns =====
# map: transform
[1, 2, 3].map { |x| x * x } # [1,4,9]
# select / reject: filter
[1, 2, 3, 4].select(&:even?) # [2,4]
[1, 2, 3, 4].reject(&:even?) # [1,3]
# reduce / inject: aggregate
[1, 2, 3, 4].sum # 10
[1, 2, 3, 4].reduce(0) { |s, x| s + x }
[1, 2, 3, 4].reduce(:*) # 24
# each_with_index:
['a','b','c'].each_with_index { |x, i| puts "#{i}: #{x}" }
# each_slice / each_cons:
(1..10).each_slice(3) { |s| p s } # [1,2,3] [4,5,6] [7,8,9] [10]
(1..5).each_cons(2) { |c| p c } # [1,2] [2,3] [3,4] [4,5]
# zip:
[1,2,3].zip(['a','b','c']) { |pair| p pair }
# ===== Breaking + next =====
[1,2,3,4,5].each do |x|
next if x.even?
break if x > 3
puts x
end
# ===== Returning a value from a block =====
result = [1,2,3].each_with_object([]) do |x, acc|
acc << x * 2 if x.odd?
end
# result = [2, 6]
# ===== Patterns to internalise =====
# - Prefer each / map / select over explicit while loops
# - Use ranges + step / upto / downto for numeric loops
# - each_slice / each_cons / zip for advanced iteration
# - Symbol shorthand (&:method) for terse callbacks
# ===== Pitfalls =====
# - 'for x in arr' adds x to the enclosing scope (use .each instead)
# - while modifying the array you are iterating -> surprises
# - Forgetting next / break short-circuits the current iteration
# - reduce without an initial value on an empty collection raises
Why it matters
Ruby loops are mostly iterators with blocks. each, map, select, reduce cover most needs; ranges + upto / downto / step handle numeric loops; each_slice / each_cons / zip handle advanced cases. Reach for explicit while only when you genuinely need it.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
i = 0
while i < 3 do puts i; i += 1 end
3.times { |i| puts i }
[:a, :b].each { |x| puts x }
Try it Yourself »
Discussion
Loading…