ha = {foo: "hoge"}
ha2 = ha.dup
ha2[:foo].reverse!
# => "egoh"
ha
# => {:foo=>"egoh"}
clone
も同じ。
そこで、 AnzenHash
ですよ。
class AnzenHash < Hash
def [](key)
immutable?(value = super) ? value : value.dup
end
undef []=
private
def immutable?(value)
value.frozen? || [Fixnum, Symbol, TrueClass, FalseClass, NilClass].any?{|k| value.is_a? k }
end
end
ha = {foo: "hoge"}
ha2 = AnzenHash[ha]
ha2[:foo]
# => "hoge"
ha2[:foo].reverse!
# => "egoh"
ha2[:foo]
# => "hoge"
ha
# => {:foo=>"hoge"}
ha2[:foo] = "poyo"
NoMethodError: undefined method `[]=' for {:foo=>"hoge"}:AnzenHash
AnzenHash
は元の Hash
の内容を断固として改変できませんが……ここまでする必要がある場面ってそんなにあるのかどうか自体は謎。
immutable?
の判定について反論は受け付けます。…