Reason #149 • May 29th, 2026

Using blocks for custom control flow

Blocks can also be used to implement custom control flow patterns, where we take an existing piece of code, pass it as a block to method that controls when, whether or how that code is executed. An example from the Ruby standard library is Timeout.timeout, which executes a block of code but raises an exception if it takes longer than a specified amount of time to complete:

Ruby
require "timeout"

Timeout.timeout(3) do
  sleep(2)
  "Finished sleeping!"
end
# => "Finished sleeping!"

Timeout.timeout(1) do
  sleep(2)
end
# => raises Timeout::Error: execution expired
    

Disclaimer: You may want to avoid using Timeout.timeout unless you are in complete control of the code inside the block passed, as it can corrupt state and lead to unpredictable behavior. Better ways of handling timeouts are covered in The Ultimate Guide to Ruby Timeouts by Andrew Kane.

In any case, let's implement our own quite safe example - a with_retries method that takes a block and retries executing it a specified number of times if it encounters an exception:

Ruby
def with_retries(max_retries)
  retries = 0

  begin
    yield
  rescue
    retries += 1

    if retries <= max_retries
      puts "Retrying... (#{retries}/#{max_retries})"
      retry
    else
      raise
    end
  end
end

with_retries(3) do
  puts "Trying..."
  raise "Something went wrong!"
end
# Output:
# Trying...
# Retrying... (1/3)
# Trying...
# Retrying... (2/3)
# Trying...
# Retrying... (3/3)
# Trying...
# raises: Something went wrong! (RuntimeError)

with_retries(10) do
  puts "Trying..."
  raise "Something went wrong!" if rand < 0.8
  puts "Success!"
end
# Output will vary, but it will keep retrying until it either succeeds or reaches the max retries.
    

Pardons for describing this as "custom control flow", which might not be the most precise term (and could probably be applied to some of the previous block articles as well), but it felt like the best way to differentiate this use case from the others.

Happy Friday! ❤️