I was going through The Well Grounded Rubyist and got confused by the following example.
Suppose we have an array of strings:
numbers = ["one", "two", "three"]
If I freeze this array, I can’t do the following:
numbers[2] = "four"
That statement is a Runtime error, but this:
numbers[2].replace("four")
is not.
The book explains that in the first of the last two statements, we are trying to access the array. That’s what I found confusing because I thought we are trying to access the third element of the array, which is a string object. And how is that different from the last statement?
It’s different because in the statement that works you are calling
String#replace. As you might expect, a call toArray#replacewill fail.The object reference at any given array index might be arbitrarily complicated and it’s not the job of the frozen array to keep those objects from changing … it just wants to keep the array from changing. You can see this:
numbers[2]has the sameobject_idafterString#replaceruns; the Array did not actually change.