Ed S. Ed S. - 1 month ago 7
Ruby Question

How does ruby serialization (Marshaling) work?

I have found some info on the subject (like this link), but nothing that tells me how it actually works under the covers. If you don't want to read the essay below, here are the real questions:


  1. How should I implement the
    marshal_dump
    and
    marshal_load
    methods? even a simple example will do.

  2. when
    marshal_load
    is called, how does it 'know' which type of object to create? If there are multiple objects of the same type in the file, how do you tell which is which? I am obviously confused...

  3. if I have an object which represents an image, is there a different way to write it out to disk?



My specific problem is this:

It is a bit complicated because I do not have the source code for the object I wish to serialize.

I am working on a mod to a game engine (RPG Maker VX using the RGSS2 game library). There is a class called Bitmap which belongs to the (closed source) API. I would like to save this object/image between game plays, so I need to serialize it to the save file. I'm not a ruby pro, but I know that I can define two methods (
marshal_dump
and
marshal_load
) which will be called by the "Marshal" module when I attempt to serialize the object.

The problem is that I do not know how to implement the two methods needed. I can actually just leave them as empty methods and it seems to work, but the object is actually disposed and the image data is gone. Besides that, I don't understand what it is doing internally and obviously creating empty methods is just wrong.

So can anyone tell me how this stuff works internally? I think that would help me to solve my problem. Beyond that, is there another type of image format that I can use which I could just save to a file and avoid doing my own serialization?

Answer

The Ruby marshalling methods store the type of the object they're encoding. The way those two hooks work is like this:

  • marshal_dump has to return some data describing the state of your object. Ruby couldn't care less about the format of this data — it just has to be something that your marshal_load method can use to reconstruct the object's state.

  • marshal_load is called on the marshalled object just after it's been recreated. It's basically the initialize method for a marshalled object. It's passed whatever object marshal_dump returned and has to use that data to reconstruct its state.

Here's an example:

class Messenger

  attr_accessor :name, :message

  def marshal_dump
    {'name' => name, 'message' => message}
  end

  def marshal_load(data)
    self.name = data['name']
    self.message = data['message']
  end

end