I have created an object that failed to marshal due to a "singleton metaclass definition executed on runtime" (Is this description of what the code does correct?).
This is performed by following code:
# define class X that my use singleton class metaprogramming features
# through call of method :break_marshalling!
class X
def break_marshalling!
meta_class = class << self
self
end
meta_class.send(:define_method, :method_y) do
return
end
end
end
# prepare my instance of X now
instance_of_x = X.new
# marshalling fine here
Marshal.dump instance_of_x
# break marshalling with metprogramming features
instance_of_x.break_marshalling!
Marshal.dump instance_of_x
# fails with TypeError: singleton can't be dumped
What can I do to make the object marshall correct? Is it possible to "remove" the singleton components from class X
of object instance_of_x
?
I really need an advise on that because of some of our objects needed to be cached through Marshal.dump serialization mechanism. This code is executed in ruby-1.9.3 but I expect it to behave similar in ruby-2.0 or ruby-2.1
You can define custom
marshal_dump
andmarshal_load
methods:If you want you can manage dynamic methods definitions via
method_missing
:I don't think there is such a thing is
remove_singleton_class_information!
, but you can try to programatically undefine things in the singleton class.According to the documentation Marshal doesn't like objects with singleton methods. With some experimentation, it seems it also doesn't like objects with a singleton class that has instance variables.
Note how hard I tried to break Marshal. I gave the singleton a class variable, an instance variable, a method, its own singleton method, and a constant. But Marshal works fine if you just remove the singleton method and the instance variable.
However, I don't think this is the right way to marshal such an object. @mdesantis's answer of defining your own
marshal_dump
andmarshal_load
is more proper.I came up with this method, which recursively removes singleton_methods from an object, and from objects assigned to instance variables:
The one-liner way to (usually) remove singleton information from
instance_of_x
: