从 Rails 4.2.7 中提取
执行:
class Object
def duplicable?
true
end
def deep_dup
duplicable? ? dup : self
end
end
class Hash
def deep_dup
each_with_object(dup) do |(key, value), hash|
hash[key.deep_dup] = value.deep_dup
end
end
end
class Array
def deep_dup
map { |it| it.deep_dup }
end
end
# Not duplicable?
# if ruby version < 2.0 also add Class and Module as they were not duplicable until 2.0
[Method, Symbol, FalseClass, TrueClass, NilClass, Numeric, BigDecimal].each do |m|
m.send(:define_method, :duplicable?, ->{false})
end
然后您可以使用一种方法,init_value
以便deep_dup
始终调用它并且您不会意外忘记
#since you asked for a constant
INIT_VALUE = { "a" => { "b" => "c" } }.freeze
def init_value
INIT_VALUE.deep_dup
end
和这样的用法
prepare = init_value
prepare["a"]["x"] = "y"
prepare2 = init_value
prepare2["a"]["y"] = "x"
prepare
#=> {"a"=>{"b"=>"c", "x"=>"y"}}
prepare2
#=> {"a"=>{"b"=>"c", "y"=>"x"}}