From: Joel VanderWerf Date: 2006-02-08T08:58:50+09:00 Subject: Re: marshalling constants Brian Buckley wrote: >> >> class A >> A1 = new >> >> def self.name_for_constant obj >> @name_for_constant ||= {} >> @name_for_constant[obj] ||= constants.find {|c| const_get(c) == obj} >> end >> >> def _dump(limit) >> self.class.name_for_constant(self) >> end >> >> def self._load(str) >> const_get str >> end >> end > > > > Whoa. I see it works (for the A constants only as written, getting > TypeErrors on A non-constants). I don't understand why it works just yet. > Will examine further tonight. > I see your point. This implementation can't marshal anonymous instances: anonymous = A.new Marshal.dump(anonymous) # ==> type error One way around this is to subclass (instances of the subclass are the only ones that can be assigned to constants), but that may not be acceptable to you. class A #... end class AConstant A1 = new def self.name_for_constant obj @name_for_constant ||= {} @name_for_constant[obj] ||= constants.find {|c| const_get(c) == obj} end def _dump(limit) self.class.name_for_constant(self) end def self._load(str) const_get str end end before = AConstant::A1 after = Marshal.load(Marshal.dump(before)) puts before == after puts before.object_id == after.object_id anonymous = A.new p Marshal.load(Marshal.dump(anonymous)) It would be better to put some logic in the _dump and _load methods to handle the two cases in one class. The problem is that there is no way to call "super" in _dump to handle the case of anonymous objects, which should be dumped in the "normal" way. This is unfortunately the way marshalling is structured in ruby... -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407