Chapter 14. YAML

image with no caption

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.

Note

YAML is an acronym that is (debatably) either short for Yet Another Markup Language or (recursively) for YAML Ain’t Markup Language.

Converting to YAML

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

Note

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
..................Content has been hidden....................

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