misterinevitable

Predefined global `$!`

$! refers to the last error raised.

begin
  raise StandardError.new("Hey there, I am an error!")
rescue
  puts "$! is a #{$!.class.name}"
end

puts "$! is a #{$!.class.name}"

Notice that $! becomes nil after the rescue clause completes.

In this case, it’s clearer to declare a variable:

begin
  # ...
rescue => e
  # ...
end

The one use case I am aware of for $! is converting an exception to a value using inline-rescue.

value_or_error = {}.fetch(:name) rescue $!
puts value_or_error.class.name # => KeyError

This allows you to succinctly capture the exception for logging or processing some other way without cluttering up your method with begin and rescue blocks. See this graceful.dev video for more information on using inline-rescue.

See also the list of predefined globals.