From: "Ara.T.Howard" Date: 2005-09-26T10:34:12+09:00 Subject: Re: Concerning Marshalling On Sun, 25 Sep 2005, christophe.poucet@gmail.com wrote: > Hello, > > I was trying to marshal some objects, however some of these objects > contain references to singletons which of course can't be marshalled. > That's why I tried something as follows: > > class Container > end > > class SpecialContainer < Container > include Singleton > end > > class Test > attr_accessor :container > def _dump(depth) > old = @container > if old == SpecialContainer.instance > @container = nil > end > result = super > @container = old > return result > end > def self._load(str) > super > if @container == nil > @container = SpecialContainer.instance > end > self > end > end > > Sadly, however, it seems there is no default implementation for _dump, > which means that in this case the super call results in a > NoMethodError. Is there any other way to resolve this problem without > custom-coding a full _dump method? > > Regards, > Christophe for some reason the mailing list seemed to have eaten my post about this so here it is again - sorry if it's a dup: harp:~ > cat dumpable_singleton.rb module DumpableSingleton module InstanceMethods attr_accessor 'ikey' def _dump *a, &b Marshal::dump ikey, *a, &b end def == other self.ikey == other.ikey end alias_method 'eql?', '==' end module ClassMethods def new *a, &b ikey = [] ikey.push *a ikey.push b if b if instances.has_key? ikey instances[ ikey ] else begin ikey.each{|k| Marshal::dump k} rescue TypeError, Exception raise ArgumentError, "all arguments must be dumpable!" end instances[ (obj = super(*a, &b)).ikey = ikey ] = obj end end def _load buf, *a, &b new(*(ikey = Marshal::load(buf, *a, &b))) end attr_accessor 'instances' end def self::included other other.module_eval{ include InstanceMethods } other.extend ClassMethods other.instances = {} other end end class C include DumpableSingleton def initialize(*a, &b); end end x = C::new 42 y = C::new 42 z = C::new 43 puts '-' * 42 C::instances.each {|k,c| p k => c} p x == y p x == z p y == z xd, yd, zd = [x, y, z].map{|c| Marshal::load(Marshal::dump(c))} puts '-' * 42 C::instances.each {|k,c| p k => c} p xd == yd p xd == zd p yd == zd puts '-' * 42 C::instances.each {|k,c| p k => c} p x == xd p y == yd p z == zd harp:~ > ruby dumpable_singleton.rb ------------------------------------------ {[43]=>#} {[42]=>#} true false false ------------------------------------------ {[43]=>#} {[42]=>#} true false false ------------------------------------------ {[43]=>#} {[42]=>#} true true true i've used something like this in in a few small projects. hth. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================