I have a class that overrides freeze:

  class Foo
    def initialize
      @x = Container.new
    end
    def freeze
      @x.each { |x| x.freeze }
      @x.freeze
      super
    end
  end

However, it's possible that any of the calls to freeze, or even the call
to each(), could throw an exception.  In that case, I don't want to
leave my object in a half-frozen state.  So I do this:

  class Foo
    def freeze
      undo = []
      begin
        @x.each do |x|
          if not x.frozen? then
            x.freeze
            undo.push proc { x.unfreeze }
          end
        end
        if not @x.frozen? then
          @x.freeze
          undo.push proc { @x.unfreeze }
        end
        super
      rescue Exception
        undo.each { |u| u.call }
        raise $!, $!.message, $!.backtrace
      end
    end
  end

(It's actually a little more complicated than this, since I have to make
sure objects get properly unfrozen even when undo.push fails).

I have implemented a simple unfreeze in an extension.  The problem,
though, as someone pointed out to me recently, is that unfreeze is not
safe, particularly on strings.  The likelihood of Ruby making a copy of
one of the frozen objects in @x while I'm freezing is low, but it could
happen.  So this is not a good solution.

Is there an exception-safe way that I can freeze sub-objects?

Paul