Add FrozenError as a subclass of RuntimeError
Currently, attempting to modify a frozen object leads to a
RuntimeError exception. Unfortunately, this means it is not easy to differentiate exceptions raised from attempting to modify frozen objects from generic exceptions such as calling
Kernel#raise with no exception class.
The attached patch adds
FrozenError as a subclass of
RuntimeError, and uses
FrozenError instead of
RuntimeError for exceptions raised when there is an attempt to modify a frozen object. It should be backwards compatible in the sense that:
begin "a".freeze << b rescue RuntimeError end
Will still function as before.
More people in the ruby community are starting to use frozen objects for the benefits of immutability (thread-safety, cache-ability, referential transparency), and having an exception class dedicated to misuse of frozen objects will make it easier to handle those exceptions.
The attached patch is a little long, mostly because ruby's test suite is currently brittle in regards to handling exception classes. For example,
assert_raise(RuntimeError) needs to be changed to
instance_of? instead of
kind_of? if given an exception class and not a module. Both RSpec and recent versions of Minitest should automatically handle this type of change without code modifications.