From: Joel VanderWerf Date: 2005-10-01T09:33:47+09:00 Subject: Re: Concerning Marshalling christophe (dot) poucet (at) gmail (dot) com wrote: > Concerning tracking references. > > I want to store each object as a separate value. I can assure that > each object has a unique id (all the objects that need to be stored > separately are instance_of? Managed), however if I marshal the objects > one by one, then the references they might hold internally to each > other will of course no long work. How would I solve this problem? > Obviously I need to replace the references by some sort value that > refers to it, or otherwise anything that is referred will be stored > multiple times. However I'm not quite sure how to put the hooks in > place for this. > > Christophe. > Here's one way: class Node @@nodes = Hash.new {|h,k| raise ArgumentError, "Missing node #{k.inspect}"} # The id of a node can be anything but +nil+. attr_reader :id def initialize id @id = id @@nodes[id] = self end attr_accessor :prev_node, :next_node attr_accessor :temp_data # don't want this to persist (maybe it's a cache, or simply # undumpable, like a proc, or a file, or a singleton). def marshal_dump [prev_node, next_node].map {|node| node && node.id} end def marshal_load(dumped_obj) @prev_node, @next_node = dumped_obj.map do |node_id| node_id.nil? ? nil : @@nodes[node_id] end end def self.delete id @@nodes.delete id end end node1 = Node.new "One" node2 = Node.new 2 node1.next_node = node2 node2.prev_node = node1 node1.temp_data = STDOUT node2.temp_data = proc {"foo"} p node1 node1_dumped = Marshal.dump(node1) p Marshal.load(Marshal.dump(node1)) Node.delete 2 p Marshal.load(node1_dumped) # This should raise an exception, to show that the referred node is not # stored in node1_dumped, and not in the @@nodes hash. __END__ #, @id="One", @next_node=#, @id=2, @prev_node=#>> #, @id=2, @prev_node=#, @id="One", @next_node=#>>, @prev_node=nil> marshal-refs2.rb:2: Missing node 2 (ArgumentError) from marshal-refs2.rb:2:in `call' from marshal-refs2.rb:24:in `default' from marshal-refs2.rb:24:in `[]' from marshal-refs2.rb:24:in `marshal_load' from marshal-refs2.rb:23:in `map' from marshal-refs2.rb:23:in `marshal_load' from marshal-refs2.rb:47:in `load' from marshal-refs2.rb:47 -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407