Ruby 3.0 Freezes Range Objects
October 01, 2020
In past, Ruby had made some of the objects frozen by default and those were the objects of Symbol
, Integer
, Float
, TrueClass
, FalseClass
, NilClass
, etc.
Ruby core team has been very cautious in past while making any object frozen
to ensure these changes do not break programmer's code. A similar decision has been taken in Ruby 3.0 to make range objects frozen by default and this is an experimental change as of now.
# Ruby 2.7.1 or earlier versions
(1..10).frozen?
#=> false
r = (1..10).freeze
r.frozen?
#=> true
# Ruby 3.0
(1..10).frozen?
#=> true
In Ruby, it is very rare to see code where we have to modify a range once it is defined.
But still there are some cases where it is possible to add a singleton method to a range.
Let's see an example:
# Ruby 2.7.1
r = 1..10
r.instance_eval { def odds; to_a.select(&:odd?) end }
r.odds
#=> [1, 3, 5, 7, 9]
In the above example, we are defining odds
method for the range object and then calling r.odds
simply returns the odd numbers from the range.
This example would work fine in Ruby 2.7.1 and earlier versions.
But it will raise FrozenError (can't modify frozen object: 1..10)
in Ruby 3.0, since range objects are frozen by default.
Here is the link to the relevant discussion.
info@scriptday.com