From: Erik Veenstra Date: 2007-01-19T22:55:28+09:00 Subject: Re: Hash#open! / Hash#close! What about this one? It uses my personal, small, generic delegator. There's at least one thing I don't like: Since it's a delegator, operations on h2 directly affect h1. A pure functional approach would be more appropriate: Going from h1 to h2 results in a copy of the data. When un_delegate'ing, we should once again copy the data. But that consumes a bit more memory... ;] (I'll work out the functional one and post it in a couple of minutes...) gegroet, Erik V. - http://www.erikveen.dds.nl/ ---------------------------------------------------------------- module EV class Delegator def initialize(real_object) @real_object = real_object end def method_missing(method_name, *args, &block) @real_object.__send__(method_name, *args, &block) end def self.delegate(*args, &block) res = self.new(*args) end def self.un_delegate(delegator_object) delegator_object.instance_variable_get("@real_object") end def self.open(*args, &block) res = delegate(*args) if block begin block.call(res) ensure res = un_delegate(res) end end res end end end class HashWithMethods < EV::Delegator def method_missing(method_name, *args, &block) method_name = method_name.to_s if method_name =~ /=$/ key = method_name[0..-2] value = args[0] @real_object[key] = value else key = method_name @real_object[key] end end end if __FILE__ == $0 h1 = {"a"=>111, "b"=>222} HashWithMethods.open(h1) do |h2| h2.b = 22222 h2.c = 33333 end p h1 end ----------------------------------------------------------------