A
Austin Ziegler
This is the reason why there are design approaches and even
language features meant to support encapsulating such aliasing
within manageable boundaries while still permitting arbitrary
object graph structures within them. Such things might not be in
Ruby, but that does not make them less worth considering.
To me, the issue is simple. If you want to freeze more than the
references you hold, do the following:
# This is a good argument for a "Mappable" or "Hashable" module
# or perhaps a changed each_with_index for Hash so that it does
# |value, key| instead of |[value, key], pseudo-index|.
module DeepFreeze
def freeze
if self.kind_of?(Hash)
self.each { |k, v| self[k.dup.freeze] = v.dup.freeze }
elsif self.respond_to?map)
self.map { |el| el.dup.freeze }
end
self.instance_variables.each do |iv|
self.instance_variable_set(iv,
self.instance_variable_get(iv).dup.freeze)
end
end
end
It isn't completely a deep freeze, as it doesn't completely traverse
the object tree, but that could be added.
-austin