Ruby 2.5 introduces FrozenError class
Recently Ruby 2.5 was released
Ruby 2.5 introduces FrozenError class which is a subclass of RuntimeError class. This change is introduced to differentiate exceptions raised from attempting to modify a frozen object from generic exceptions. Let’s take few examples to learn about the change.
String
Prior to Ruby 2.5
2.4.0 :001 > NAME = 'Atul'.freeze
=> "Atul"
2.4.0 :002 > NAME << 'JOY'
RuntimeError: can't modify frozen String
from (irb):2
from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
Ruby 2.5
2.5.0 :001 > NAME = 'Atul'.freeze
=> "Atul"
2.5.0 :002 > NAME << 'Joy'
Traceback (most recent call last):
2: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
1: from (irb):2
FrozenError (can't modify frozen String)
Array
Prior to Ruby 2.5
2.4.0 :001 > a = [1, 2, 3]
=> [1, 2, 3]
2.4.0 :002 > a.freeze
=> [1, 2, 3]
2.4.0 :003 > a << 4
RuntimeError: can't modify frozen Array
from (irb):3
from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
Ruby 2.5
2.5.0 :001 > a = [1, 2, 3]
=> [1, 2, 3]
2.5.0 :002 > a.freeze
=> [1, 2, 3]
2.5.0 :003 > a << 4
Traceback (most recent call last):
2: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
1: from (irb):3
FrozenError (can't modify frozen Array)
Hash
Prior to Ruby 2.5
2.4.0 :001 > h = {a: 1}
=> {:a=>1}
2.4.0 :002 > h.freeze
=> {:a=>1}
2.4.0 :003 > h.delete(:a)
RuntimeError: can't modify frozen Hash
from (irb):3:in `delete'
from (irb):3
from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
Ruby 2.5
2.5.0 :001 > h = {a: 1}
=> {:a=>1}
2.5.0 :002 > h.freeze
=> {:a=>1}
2.5.0 :003 > h.delete(:a)
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):3
1: from (irb):3:in `delete'
FrozenError (can't modify frozen Hash)
Object
Prior to Ruby 2.5
2.4.0 :001 > o = Object.new.freeze
=> #<Object:0x007fce5919ad50>
2.4.0 :002 > o.taint
RuntimeError: can't modify frozen Object
from (irb):2:in `taint'
from (irb):2
from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
Ruby 2.5
2.5.0 :001 > o = Object.new.freeze
=> #<Object:0x000055c909144ce0>
2.5.0 :002 > o.taint
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):2
1: from (irb):2:in `taint'
FrozenError (can't modify frozen Object)