At some point, most desktop applications are going to want to save and read structured data to and from disk. You’ve already seen how to read and write data using simple IO routines such as gets
and puts
. But how would you go about saving and restoring data from, say, lists of mixed object types? One simple way of doing this with Ruby is by using YAML.
YAML is an acronym that is (debatably) either short for Yet Another Markup Language or (recursively) for YAML Ain’t Markup Language.
YAML defines a serialization (data-saving) format that stores information as human-readable text. YAML can be used with a variety of programming languages; in order to use it in Ruby, your code needs access to routines from Ruby’s yaml.rb file. Generally, this would be done by loading or “requiring” the file at the top of a code unit like this:
require "yaml"
Having done this, you will have access to a variety of methods to convert Ruby objects to the YAML format so that they can write their data to a file. Subsequently, you will be able to read back this saved data and use it to reconstruct Ruby objects. To convert an object to YAML format, you can use the to_yaml
method. This will convert standard object types such as strings, integers, arrays, hashes, and so on. For example, this is how you would convert a string:
to_yaml1.rb
"hello world".to_yaml
And this is how you would convert an array:
["a1", "a2" ].to_yaml
This is the YAML format that you would obtain as a result of this array conversion:
--- - a1 - a2
Notice the three dashes that define the start of a new YAML “document” and the single dash that defines each new element in a list. In YAML terms, a document is not a separate file on disk but a separate YAML definition; one disk file may contain many YAML documents. For more information on the YAML format, refer to Digging Deeper in Digging Deeper.
You can also convert objects of nonstandard types to YAML. For example, let’s suppose you create this class and object:
to_yaml2.rb
class MyClass def initialize( anInt, aString ) @myint = anInt @mystring =aString end end ob1 = MyClass.new( 100, "hello world" ).to_yaml
The YAML representation of this object will be preceded by the text !ruby/object:
followed by the class name, the names of variables with a colon appended (but minus the @
), and their values, one per line:
--- !ruby/object:MyClass myint: 100 mystring: hello world
If you want to print out the YAML representation of an object, you can use the method y()
, which is a sort of YAML equivalent of the familiar p()
method used to inspect and print normal Ruby objects:
yaml_test1.rb
y( ['Bert', 'Fred', 'Mary'] )
This displays the following:
--- - Bert - Fred - Mary
You could similarly display a hash:
y({ 'fruit' => 'banana', :vegetable => 'cabbage', 'number' => 3 })
in which case each key-value pair is placed onto a new line:
--- fruit: banana :vegetable: cabbage number: 3
The ordering of hash elements may differ according to which version of Ruby you are using (see Chapter 4). It is best to assume no intrinsic order when working with a hash.
Or you could display your own “custom” objects:
t = Treasure.new( 'magic lamp', 500 ) y( t )
This displays data formatted, as in the earlier example where I used to_yaml
, with the class name at the top and with pairs of variable names and values on successive lines. This is the YAML representation of a Treasure object containing the instance variables @name
and @value
:
--- !ruby/object:Treasure name: magic lamp value: 500
You can even use y()
to display quite complex objects such as nested arrays:
yaml_test2.rb
arr1 = [ ["The Groovesters", "Groovy Tunes", 12 ], [ "Dolly Parton", "Greatest Hits", 38 ] ] y( arr1 )
This is the YAML representation of arr1
:
--- - - The Groovesters - Groovy Tunes - 12 - - Dolly Parton - Greatest Hits - 38
Here is another example of an array containing objects of user-defined types:
class CD def initialize( anArtist, aName, theNumTracks ) @artist = anArtist @name = aName @numtracks = theNumTracks end end arr2 = [CD.new("The Beasts", "Beastly Tunes", 22), CD.new("The Strolling Bones","Songs For Senior Citizens",38) ] y( arr2 )
This outputs the following YAML:
--- - !ruby/object:CD artist: The Beasts name: Beastly Tunes numtracks: 22 - !ruby/object:CD artist: The Strolling Bones name: Songs For Senior Citizens numtracks: 38
13.59.227.82