From: Evan Martin Date: 2002-06-05T03:59:13+09:00 Subject: Re: When should actually freeze work ? 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 :) 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. -- Evan Martin martine@cs.washington.edu http://neugierig.org