There are times when you've worked hard to make your object exactly
right, and you'll be damned if you'll let anyone just change
it. Perhaps you need to pass some kind of opaque object between two of
your classes via some third-party object, and you want to make sure it
arrives unmodified. Perhaps you want to use an object as a hash key, and
need to make sure that no one modifies it while it's being used.
Perhaps something is corrupting one of your objects, and you'd like
Ruby to raise an exception as soon as the change occurs.
Ruby provides a very simple mechanism to help with this. Any object can be
frozen by invoking
Object#freeze
. A frozen object may
not be modified: you can't change its instance variables (directly or
indirectly), you can't associate singleton methods with it, and, if it
is a class or module, you can't add, delete, or modify its
methods. Once frozen, an object stays frozen: there is no
Object#thaw
. You can test to see if an object is frozen using
Object#frozen?
.
What happens when you copy a frozen object? That depends on the method
you use. If you call an object's
clone
method, the entire
object state (including whether it is frozen) is copied to the new
object. On the other hand,
dup
typically copies only the
object's contents---the new copy will not inherit the frozen status.
str1 = "hello"
|
str1.freeze
|
� |
"hello"
|
str1.frozen?
|
� |
true
|
str2 = str1.clone
|
str2.frozen?
|
� |
true
|
str3 = str1.dup
|
str3.frozen?
|
� |
false
|
Although freezing objects may initially seem like a good idea, you
might want to hold off doing it until you come across a real
need. Freezing is one of those ideas that looks essential on paper but
isn't used much in practice.