Ruby's redo, retry and next keywords
Tags: ruby, exceptions, beginners, learning
Published: 2018-06-05 15:12:30

---
title: Ruby's redo, retry and next keywords
author: Thijs Cadier
description: We've talked about the retry keyword before. Its little-known counterpart redo works similarly, but reruns loop iterations instead of whole blocks.
cover_image: https://blog.appsignal.com/images/blog/2018-06/black-color-paint.jpg
tags: #ruby #exceptions #beginners #learning
canonical_url: https://blog.appsignal.com/2018/06/05/redo-retry-next.html
published: true
---

We've talked about the `retry` keyword while discussing [retrying after exceptions](https://blog.appsignal.com/2018/05/16/ensure-retry-and-reraise-exceptions-in-ruby.html). Its little-known counterpart `redo` works similarly, but re-runs loop iterations instead of whole blocks.

## The `redo` keyword

As we learned in the previous Academy article, `retry` lets you retry a piece of code in a block:

```ruby
begin
  puts "Iteration"
  raise
rescue
  retry
end
```

This example prints the word "Iteration" to the console before raising an exception. The rescue blocks executes, which calls `retry` and starts the block again from the beginning. This results in our program endlessly printing `Iteration`. The `redo` keyword lets you achieve a similar effect when using loops. This is useful in situations where you need to retry while iterating for example.

```ruby
10.times do |i|
  puts "Iteration #{i}"
  redo if i > 2
end
```

This will print:

```
$ ruby redo.rb
Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 3
Iteration 3
...
```

Notice how the iteration count stays the same? It will step back execution to the start of the loop. This variant of the code using `retry` will print the exact same output:

```ruby
10.times do |i|
  begin
    puts "Iteration #{i}"
    raise if i > 2
  rescue
    retry
  end
end
```

You can use `redo` to implement retrying in a loop. In the next example we have a queue of jobs. They either return `:success` or `:failure`. We keep re-running the same iteration of the loop until the job succeeds.

```ruby
[job_1, job_2, job_3, job_4].each do |job|
  redo unless job.call == :success
end
```

## Ruby 1.8
The behavior of <code>retry</code> and <code>redo</code> changed between Ruby 1.8 and 1.9. They used to restart the loop's iteration, but both in a different way. From 1.9, <code>retry</code> only works with a <code>begin</code>/<code>rescue</code> block and <code>redo</code> only works within loops.

## The `next` keyword

If you want to move to the next iteration of the loop, as opposed to moving back to the start of the current one, you can use `next`.

```ruby
10.times do |i|
  puts "Iteration #{i}"
  next if i > 2
  puts "Iteration done"
end
```

This will print:

```
$ ruby next.rb
Iteration 0
Iteration done
Iteration 1
Iteration done
Iteration 2
Iteration done
Iteration 3
Iteration 4
...
```

See how the iteration counter keeps incrementing? In most cases using `next` is what you want. Look at `redo` if you need a loop that runs an exact number of times or needs error handling when iterating over an array.

We hope you learned something new about redoing iterations in loops and would love to know what you thought of this article (or any of the other ones in the [AppSignal Academy series](https://blog.appsignal.com/category/academy.html)). Please don't hesitate to let us know in the comments what you think, or if you have any Ruby subjects you'd like to learn more about.