From: Eric Wong Date: 2016-01-20T09:47:02+00:00 Subject: [ruby-core:72970] Re: [Ruby trunk - Bug #12008] [Open] Immutable object graphs (a.k.a. deep freeze) bascule@gmail.com wrote: > I think immutable state has huge benefits for a lot of areas, most > notably concurrency and security. Agree. Maybe something along the lines of the following? module DeepFreezable def deep_freeze_check!(obj) obj.frozen? or raise TypeError, "#{obj.inspect} not frozen in #{inspect}" end def ivar_deep_frozen? instance_variables.each do |iv| deep_freeze_check!(instance_variable_get(iv)) end end end class Array include DeepFreezable def deep_freeze ivar_deep_frozen? each { |obj| deep_freeze_check!(obj) } freeze end end class String include DeepFreezable def deep_freeze ivar_deep_frozen? freeze end end class Hash include DeepFreezable def deep_freeze ivar_deep_frozen? each do |key, val| deep_freeze_check!(key) deep_freeze_check!(val) end freeze end end require 'test/unit' class TestDeepFreeze < Test::Unit::TestCase def test_deep_freeze assert_predicate({}.deep_freeze, :frozen?) assert_raise(TypeError) { {'foo' => 'bar'.dup }.deep_freeze } assert_predicate({'foo' => 'bar'.freeze }.deep_freeze, :frozen?) assert_raise(TypeError) { %w(a b c).map(&:dup).deep_freeze } assert_predicate(%w(a b c).map(&:freeze).deep_freeze, :frozen?) s = String.new s.instance_eval { @foo = 'bar'.dup } assert_raise(TypeError) { s.deep_freeze } s.freeze assert_raise(TypeError) { s.deep_freeze } s.instance_variable_get(:@foo).freeze assert_predicate s.deep_freeze, :frozen? end end Unsubscribe: