Lesson Weekend

Creating loops in Ruby is conceptually quite similar to the way we handle loops in JavaScript. In this lesson, we’ll take a look at times, each, while and until loops. We’ll also take a quick look at plain old loops and the break keyword, which we can use to break out of a loop at any time.

Times Loops


One of the most basic loops in Ruby is the times loop. Here's an example:

> number = 0
> 5.times() do
  number = number + 1
end
=> 5

The times loop will run the number of times we specify, which is 5 times in this case. Each time through the loop, number is incremented by 1.

There's one other thing to note here: we're not defining a method. Instead, we're just passing a block to the times method. We always need to pass a block with instructions (code) to our loops. The block begins with do and finishes with end.

If we wanted, we could pass an argument into a times loop like this: 5.times do |t|. (We can name the parameter whatever we like.) The value of t each time through the loop is the number of times the loop has run (the index of the loop), starting with with 0.

This kind of loop isn't very common, but there are times when you'll find it useful. The each loop, on the other hand, is probably the most common and useful looping technique in Ruby.

Each Loops


Each loops are particularly useful for looping through collections. A collection could be an array, range or hash (which we haven't covered yet). Let's say we want to multiply each value inside an array by 2. We’ll create a method called array_doubler to do this.

def array_doubler(array)
  new_array = []
  array.each do |array_element|
    new_array.push(array_element * 2)
  end
  new_array
end
> array_doubler([1,2,3])
=> [2,4,6]

We start by passing an array of values into our array_doubler method. Before we iterate over the values, though, we create a new array. In this case, the each loop won't actually modify the receiver, so we’ll need to push the values into the new array. A common mistake for beginners is assuming that methods inside a loop will change the receiver. Sometimes that's the case, such as with bang methods, but sometimes we need to push the values into a new array as we do above.

Just like with the times loop, we also use slightly different syntax to pass an argument into our each loop. Instead of parentheses, we surround our parameter with | symbols. (We'll get an error if we use parentheses.) An each loop should always have the following syntax: collection.each do |element|.

In the array_doubler method, the each loop iterates through each element in the array, passing the element into our array_element parameter one at a time. We double the array_element and then push that value into new_array. Finally, when the loop is done, we implicitly return new_array.

We can also iterate over other collections, so let’s look at an example of using each to iterate over a range.

> numbers = (1..10)
> sum = 0
> numbers.each() do |number|
  sum = sum + (number)
end
> sum
=> 55

You’ll be using each loops very regularly in Ruby, so take the time to practice creating some methods with loops on your own!

While and Until Loops


A while loop runs while a condition is true. An until loop runs until a condition becomes false. It’s very important that you choose a condition that will eventually be met; otherwise, you’ll have an infinite loop.

Here’s an example of a while loop:

> x = 0
> array = []
> while (x < 10 )
  x = x + 1
  array.push(x)
end
> array
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Our while loop continues as long as x is less than 10. So why does our final array include the element 10 at the end? The last time through the loop, x is 9. We increment x by 1 and 10 is pushed to the array.

You’ll also notice that we’ve declared x and array outside of the loop. If x were declared inside the loop, the value of x would never be greater than 1 and we’d end up with an infinite loop. If array were declared inside the loop, it would be reinitialized as [] each time we went through the loop and the final result would be an empty array.

These are common errors you’ll encounter with looping in general, especially at the beginning, so always make sure to declare these variables outside of the loop.

An until loop is essentially the opposite of a while loop. We could easily rewrite the loop above with an until loop instead.

x = 0
array = []
until (x >= 10 )
  x = x + 1
  array.push(x)
end
array
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

If you’re making a choice between a while and until loop, opt for the clearest and most readable of the two.

Plain Old Loops and the break Keyword


Let’s cover one last loop. You won’t see this one very much but you should still be aware of it. We’ll also take a look at the break keyword, which we can use in any loop. We can create a simple loop without conditions by using loop do...end.

Here’s an example. Be ready to use Ctrl + c to escape if you try it out.

loop do
  puts "hi"
end

puts logs information to the REPL. In this case, hi.

If you run this loop, it will run the loop indefinitely. The only way to escape is to force it to quit. This kind of loop may not seem very useful, and it’s certainly less flexible than other Ruby loops, but we can make it more workable with the break keyword.

The break keyword terminates a loop and we can use it with any Ruby loop. Here’s an example of how we could use loop and break to output hi to the terminal ten times.

> counter = 0
> loop do
  counter += 1
  if counter > 10
    break
  end
  puts "hi"
end
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
=> nil

Since our loop doesn't actually return anything, we get a return value of nil.

Counters are very, very common in programming languages, and we use one here. Each time through the loop, we increment our loop by one. We’re using shorthand here; counter += 1 is the same as counter = counter + 1.

If the counter is greater than 10, our loop will break. If not, hi will be outputted to the terminal.

You probably won’t use plain old loops much, but the break keyword can be very useful.

In this lesson, we’ve covered the basics of looping in Ruby. Most of the time you’ll use each loops, but while and until loops can also be very useful. And while you’re less likely to use a plain old loop or a times loops, they can still come in handy. We’ve also covered the break keyword, which can be used any time you need to break out of a loop. And with that, it’s time to break away from loops, at least for now!

Times Loop Example


number = 0
5.times() do
  number = number + 1
end

Each Loop Example


def array_doubler(array)
  new_array = []
  array.each do |array_element|
    new_array.push(array_element * 2)
  end
  new_array
end

While and Until Loops

Here’s an example of a while loop:

x = 0
array = []
while (x < 10 )
  x = x + 1
  array.push(x)
end

Here's an example of an until loop:

x = 0
array = []
until (x >= 10 )
  x = x + 1
  array.push(x)
end

Loop and the break Keyword


counter = 0
loop do
  counter += 1
  if counter > 10
    break
  end
  puts "hi"
end

Lesson 6 of 10
Last updated August 7, 2022