This is an interesting one most people don't know or consider in their day-to-day Ruby coding: how Exception Handling works. More specifically, how naming which exceptions to handle works.
When we need to catch an exception:
begin raise "Silly Error" rescue StandardError, RuntimeError => err p err end
we name the exception types to catch: StandardError, RuntimeError. We can actually put arbitrary code there:
begin raise "Silly Error" rescue (puts 'picking a class'; [IOError, RuntimeError].shuffle.first) => err end
which sometimes returns err, the exception object, and sometimes doesn't catch the RuntimeError! That's important to note: like optional arguments, the "which exceptions should I catch" code is invoked each time it is encountered.
Of course, we shouldn't stop there. Exactly what happens after that "which exception" code is evaluated? It turns out, it's our favorite Ruby pattern matcher at work: #===.
As you likely know, Module#=== returns true if it is passed an instance of the given module/class. So when you write:
begin raise StandardError.new('something') rescue IOError, StandardError => err error_handling() end
When the exception hits, Ruby runs the equivalent of:
if ([IOError, StandardError].any? { |type| type === $! }) err = $1 error_handling() else raise err end
That means, in the Ruby tradition, we can do all kinds of horrible things (kidding!):
BigErrorMessagesOnly = Object.new def BigErrorMessagesOnly.===(other) other.message.size > 50 end
This little object BigErrorMessagesOnly will only match exceptions with messages longer than 50 characters. Can't have non-descriptive error messages, can we?
begin raise 'something' rescue BigErrorMessagesOnly end #=> RuntimeError: something begin raise 'a very long message' * 10 rescue BigErrorMessagesOnly puts "Saved!" end #=> "Saved!"
Naturally, this cool behavior makes static analysis harder. Laser will initially only work with classes/modules as rescue arguments, but once pure-function emulation works, any inferrably-constant argument can be discovered statically.

Enjoy this article? Then feel free to: