Skip to content
AgileLogics
5 min read

Iterators: times, each, and upto

Prerequisites: Loops: while and until

Instead of managing a counter yourself, Ruby code usually asks an object to iterate — to run a block of code once for each item. These methods are called iterators.

times

3.times do |i|
  puts "Pass #{i}"
end
Pass 0
Pass 1
Pass 2

The code between do and end is a block. |i| names the value the iterator passes in on each pass — here, the counter, starting at 0.

each

each runs the block once for every element of a collection:

fruits = ["apple", "banana", "cherry"]

fruits.each do |fruit|
  puts "I like #{fruit}"
end
I like apple
I like banana
I like cherry

each_with_index also passes the position:

fruits = ["apple", "banana"]
fruits.each_with_index do |fruit, index|
  puts "#{index + 1}. #{fruit}"
end
1. apple
2. banana

upto, downto, step

1.upto(3) { |n| print n, " " }
puts
3.downto(1) { |n| print n, " " }
puts
0.step(10, 5) { |n| print n, " " }
puts
1 2 3
3 2 1
0 5 10

do...end or braces?

Both mark a block. The convention: { ... } for a short block on one line, and do ... end for a block that spans several lines.

Ruby also has a for ... in loop, but it's rarely used — each is the idiomatic choice.

Common mistakes

  • Expecting 3.times to count from 1. It counts 0, 1, 2. Use 1.upto(3) when you need 1 to 3.

Practice

Print the 5 times table from 5 x 1 = 5 to 5 x 10 = 50.

Show solution
1.upto(10) do |n|
  puts "5 x #{n} = #{5 * n}"
end