Chapter 15. Marshal

image with no caption

An alternative way of saving and loading data is provided by Ruby’s Marshal library. This has a similar set of methods to YAML to enable you to save and load data to and from disk.

Saving and Loading Data

Compare the following program with yaml_dump2.rb from the previous chapter:

marshal1.rb

f = File.open( 'friends.sav', 'w' )
Marshal.dump( ["fred", "bert", "mary"], f )
f.close

File.open( 'morefriends.sav', 'w' ){ |friendsfile|
    Marshal.dump( ["sally", "agnes", "john" ], friendsfile )
}

File.open( 'morefriends.sav' ){ |f|
    $arr= Marshal.load(f)
}
myfriends = Marshal.load(File.open( 'friends.sav' ))
morefriends = Marshal.load(File.open( 'morefriends.sav' ))

p( myfriends )    #=> ["fred", "bert", "mary"]
p( morefriends )  #=> ["sally", "agnes", "john"]
p( $arr )         #=> ["sally", "agnes", "john"]

The two programs are pretty much identical except that each occurrence of YAML (as in YAML.dump and YAML.load) has been replaced with Marshal. Moreover, Marshal is “built in” to Ruby as standard, so you don’t have to require any extra files in order to use it.

If you look at the data files produced (such as friends.sav), you will immediately see that there is a major difference, however. Whereas YAML files are in plaintext format, Marshal files are in binary format. So although you may be able to read some characters, such as those in the strings, you won’t simply be able to load the saved data and modify it in a text editor.

As with YAML, most data structures can be automatically serialized using Marshal just by dumping the top-level object and loading it when you want to reconstruct all the objects beneath it. For an example, take a look at my little adventure game program. In the previous chapter, I explained how to save and restore a Map containing Rooms containing Treasures just by dumping and loading the Map object, mymap (see gamesave_y.rb in Adventures in YAML). You can do the same using Marshal instead of YAML:

gamesave_m.rb

File.open( 'game.sav', 'w' ){ |f|
    Marshal.dump( mymap, f )    # save data to file
}

File.open( 'game.sav' ){ |f|
    mymap = Marshal.load(f)     # reload saved data from file
}

Objects cannot be so easily serialized in a few special circumstances. These exceptions are documented in the code of Ruby’s Marshal module (marshal.c), which states, “If the objects to be dumped include bindings, procedure or method objects, instances of class IO, or singleton objects, a TypeError will be raised.” I’ll show an example of this while discussing how you might go about saving singletons with marshaling.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.197.95