7
6

More than 5 years have passed since last update.

いつから dup すれば安全だと思ってた?

Last updated at Posted at 2012-12-02
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? の判定について反論は受け付けます。…

参考 URL

7
6
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6