class ReeObject::DeepFreeze

def call(obj)

def call(obj)
  recursively_freeze(obj, {})
end

def freeze_array(array, cache)

def freeze_array(array, cache)
  array.each { recursively_freeze(_1, cache) }
  array.freeze
end

def freeze_hash(hash, cache)

def freeze_hash(hash, cache)
  hash.default.freeze
  hash.each do |k, v|
    recursively_freeze(k, cache)
    recursively_freeze(v, cache)
  end
  hash.freeze
end

def freeze_obj(obj, cache)

def freeze_obj(obj, cache)
  return obj if obj.is_a?(Class) || obj.is_a?(Module)
  return cache[obj.object_id] if cache.key?(obj.object_id)
  cache[obj.object_id] = obj
  obj.instance_variables.each do |var|
    recursively_freeze(obj.instance_variable_get(var), cache)
  end
  obj.freeze
end

def recursively_freeze(obj, cache)

def recursively_freeze(obj, cache)
  if obj.class == Array
    freeze_array(obj, cache)
  elsif obj.class == Hash
    freeze_hash(obj, cache)
  else
    freeze_obj(obj, cache)
  end
end