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: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>