You need to be careful to distinguish a frozen string from the reference
to the string. It’s a subtle distinction, especially because modifying
the actual string means that your reference
s = “abc”
Means that s now refers to the string “abc”
s.freeze
Means freeze the string that s refers to. You haven’t really changed s,
so you can reassign it.
However, if you try to modify the string itself (functions ending with a !
are good examples), the freeze works as expected:
irb(main):005:0> s = “abc”
“abc”
irb(main):006:0> s.freeze
“abc”
irb(main):007:0> s.gsub!(/a/, ‘b’)
TypeError: can’t modify frozen string
from (irb):7:in `gsub!’
from (irb):7
irb(main):008:0> s
“abc”
Here’s another exercise in how references and strings are separate.
I make b and a refer to the same string, then I change the string and
both b and a now show the change.
irb(main):001:0> a = “abc”
“abc”
irb(main):002:0> b = a
“abc”
irb(main):003:0> b.gsub!(/a/, “hello”)
“hellobc”
irb(main):004:0> b
“hellobc”
irb(main):005:0> a
“hellobc”
This is also why the function is suffixed with an exclamation-- it has
the potential to do something confusing. You may have intended to do
this, instead:
irb(main):001:0> a = “abc”
“abc”
irb(main):002:0> b = a
“abc”
irb(main):003:0> b = b.gsub(/a/, “hello”)
“hellobc”
irb(main):004:0> b
“hellobc”
irb(main):005:0> a
“abc”
Here, I reassign b to be the result of the gsub (notice there’s no ! so
it doesn’t modify the original string; it makes a new one). That leaves
the string a refers to alone.
···
On Wed, Jun 05, 2002 at 03:41:16AM +0900, Philip Mateescu wrote:
s = “abc”
s.freeze
s.frozen ? # >> true
s = “123” # doesn’t throw a can’t modify frozen string. why ?
s.frozen? # >> false (but I thought I told it to freeze 
–
Evan Martin
martine@cs.washington.edu
http://neugierig.org