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".
|