Kernel#catch

catch(tag) { block } -> value
Returns: Object · Updated March 13, 2026 · Kernel Methods
control-flow exceptions tag jump

The catch method establishes a block that can receive transfers of control from throw. Unlike exceptions, it’s designed for normal control flow, allowing early exit from nested structures.

Basic Usage

result = catch(:done) do
  throw :done if some_condition
  "completed"
end

Practical Examples

Early Exit from Nested Loops

result = catch(:found) do
  (1..10).each do |x|
    (1..10).each do |y|
      if x == 5 && y == 5
        throw :found, [x, y]
      end
    end
  end
  nil
end

puts result  # => [5, 5]

Finding Items

def find_admin(users)
  catch(:admin_found) do
    users.each do |group|
      group.each do |user|
        throw(:admin_found, user) if user[:admin]
      end
    end
    nil
  end
end

State Machine

def process_state_machine
  state = :initial
  
  catch(:terminate) do
    loop do
      case state
      when :initial
        state = :processing
      when :processing
        state = :complete
      when :complete
        throw :terminate, "Success"
      end
    end
  end
end

Return Value

# Returns block's last value if no throw
result = catch(:tag) { "normal exit" }
puts result  # => "normal exit"

# Returns thrown value if throw executes
result = catch(:tag) { throw :tag, "early exit" }
puts result  # => "early exit"

Nested catch Blocks

catch(:outer) do
  catch(:inner) do
    throw :outer, "skipped inner"
  end
  "inner block"
end
# => "skipped inner"

Tag Types

# Tags can be symbols
catch(:symbol) { }

# Or strings
catch("string_tag") { }

Comparison with Exceptions

# catch/throw - for flow control
catch(:exit) { throw :exit, result }

# raise/rescue - for error handling
begin
  raise "Error"
rescue => e
  # Handle error
end

Use Cases

  • Breaking out of nested loops cleanly
  • Implementing state machines
  • Early exit from complex algorithms
  • Search operations
  • Game AI (state transitions)

See Also