0

In one of my rails models, I save a Marshal serialized array of Classes. If I change the name of one of the classes, Marshal is no longer able to deserialize the array. Is there a way I can get the unchanged parts of the array?

Here is how you can simulate my problem in IRB

$ irb
> require 'set'
> tmp = Marshal.dump [Hash, Fixnum, Set]
> => "\x04\b[\bc\tHashc\vFixnumc\bSet"
> Marshal.load "\x04\b[\bc\tHashc\vFixnumc\bSet"
> => [Hash, Fixnum, Set] - like I want
> exit

$ irb
> Marshal.load "\x04\b[\bc\tHashc\vFixnumc\bSet"
> # throws error, but what I want is [Hash, Fixnum], or even [Hash, Fixnum, nil]

Is there any way I could conceivably do this?

Ramfjord
  • 872
  • 8
  • 14
  • I think you're out of luck. Marshal should only be used for temporary storage or transfer for objects, you shouldn't be using it to put things in your database. – mu is too short Sep 20 '12 at 02:52
  • would you recommend any other serialization formats in particular for long term storage of things like this? – Ramfjord Sep 25 '12 at 01:42
  • There's always YAML or XML. If your data types/structures fit then JSON is another option. – mu is too short Sep 25 '12 at 01:56

1 Answers1

0

In your example, you forgot to require 'set' again when you jump back into irb. I tested this and marshal will deserialize the array correctly if you do.

On a side note, a better alternative than Marshal would be to use something like Ox which serializes Ruby objects as XML. It would probably be a lot easier to work with.

Ox gem homepage

Here's an example of marshaling with Ox from the gem's homepage:

require 'ox'

class Sample
  attr_accessor :a, :b, :c

  def initialize(a, b, c)
    @a = a
    @b = b
    @c = c
  end
end

# Create Object
obj = Sample.new(1, "bee", ['x', :y, 7.0])
# Now dump the Object to an XML String.
xml = Ox.dump(obj)
# Convert the object back into a Sample Object.
obj2 = Ox.parse_obj(xml)
Josh Voigts
  • 4,114
  • 1
  • 18
  • 43
  • I didn't require set because the actual problem is that the class being deserialized is no longer in the namespace. The actual problem I had was only in by dev db, because I misspelled a class name, changed it, and all the sudden none of the arrays that had it would deserialize. I have thought about using other serializers, like json. Why would you recommend Ox? – Ramfjord Sep 25 '12 at 01:41
  • It's apples and oranges, but if you go the JSON route, I don't know of any libraries that will serialize _human readable_ objects without some work. [This post](http://stackoverflow.com/a/4464721/1177119) explains that a little more. Ox on the other hand can serialize human readable Ruby objects to xml (and claims to be faster than Marshal). Just seemed like a good alternative to Marshal to me, but there are a lot of options. – Josh Voigts Sep 25 '12 at 02:15