Patches: Browse | Submit New | Admin

[#11651] define #marshal_translate as a way to tell Marshal to "dump this object instead of the one you consider dumping"

Date:
2007-06-18 11:16
Priority:
3
Submitted By:
Sylvain Joyeux (lapinot)
Assigned To:
Yukihiro Matsumoto (matz)
Category:
Misc / Other Standard Library
State:
Open
Summary:
define #marshal_translate as a way to tell Marshal to "dump this object instead of the one you consider dumping"

Detailed description
 define #marshal_translate as a way to dump an object for another

What I'd like to achieve here is to say that an object 'a', when dumped, must be 'translated' to another object 'b'
which will be dumped instead of 'a'. The difference with marshal_dump and _dump is that the marshaled data would contain
information about neither 'a' nor the class of 'a'.

=== Use case
I have a library, available using Darcs at http://www.laas.fr/~sjoyeux/darcs/typelib, which parses C headers and produces
a set of Ruby classes which describe each types found in the C code. The object instances built from these classes can
then be used to manipulate transparently from Ruby the in-memory C structures, and call C functions. See the tests in
test/ruby for examples.
  
A set of these classes is managed by a type registry. Because two type registries can contain the same object, and because
they can contain two different types with the same name, and (finally) because there can be a lot of types, I don't
want to assign these classes to constants.

My problem, now, is to be able to pass the instances through DRb, which means to marshal/unmarshal them using Marshal.
Since the current way to define 'user' marshaling requires that the object's class has a path, it is impossible with
the current behavior of Marshal

=== Proposal
When marshaling an object, check first for a marshal_translate method. If it is defined, marshal the object returned
by this method instead (see patch)

In my case, Type#marshal_translate would look like

  class Type
    class Dumped
      def initialize(registry, name, data)
        @registry = DRbObject.new(registry)
        @name     = name
        @data     = data
      end
      def _dump(lvl); Marshal.dump([@registry, @name, @data]) end
      def self._load(str)
        reg, name, data = Marshal.load(str)
        # get back the Type class from [reg, name] and initialize
        # an instance using +data+
      end 
    end
    def marshal_translate
      Dumped.new(self.class.registry, self.class.name, to_byte_array)
    end
  end

So, when Marshal.dump(my_value) is called, an instance of Dumped is inserted into the stream. Then, at Marshal.load
time, it is Dumped._load which is called. There is therefore no need to be able to dump my_value's class, as access
to <anonymous class>._load is not needed anymore.

I think it is a valuable addition in the various ways to dump classes:
#marshal_dump/#marshal_load being the "high level" way to do it, #_dump/._load the "medium level"
and #marshal_translate the "low level".

Add A Comment: Notepad

Please login


Followup

Message
Date: 2007-06-18 12:27
Sender: Shyouhei Urabe

Assigning to matz as this is a feature request.

Attached Files:

Name Description Download
ruby-marshal_translate.diff implementation of marshal_translate Download
ruby-marshal_translate.2.diff handle #marshal_translate in DRbObject#respond_to?. Replaces the previous patch Download

Changes:

Field Old Value Date By
summarydefine #marshal_translate as a way to tell Marshal to "dump this object instead of the one you consider dumping"2007-06-20 06:32lapinot
File Added2135: ruby-marshal_translate.2.diff2007-06-20 06:32lapinot
assigned_toshyouhei2007-06-18 12:27shyouhei
summarydefine #marshal_translate as a way to tell Marshal to "dump this object instead of the one you consider dumping"2007-06-18 12:27shyouhei
File Added2126: ruby-marshal_translate.diff2007-06-18 11:16lapinot