YAML.rb has means for exporting custom objects to YAML. We've just gone over most of the types that YAML comes with, so we'll start off with some Ruby-specific types supported by YAML.rb. Then we'll cover how YAML.rb represents your custom classes.
Ruby Symbols are stored as strings with a '!ruby/symbol' (or '!ruby/sym') type applied:
simple symbol: !ruby/symbol Simple shortcut syntax: !ruby/sym Simple symbols in maps: !ruby/sym MapKey: !ruby/sym MapValue
Naturally, Symbols have their own to_yaml method:
puts :Simple.to_yaml # prints: # --- !ruby/sym Simple
Ranges are store as strings with a '!ruby/range' type. The string is syntactically identical to the Range syntax in your Ruby code:
normal range: !ruby/range 10..20 exclusive range: !ruby/range 11...20 negative range: !ruby/range -1..-5 ? !ruby/range 0..40 : range as a map key
You may use any YAML basic type in your Range, including Integers, Floats, Dates, and Timestamps.
floats: !ruby/range 10.2..21.5 dates: !ruby/range 2001-03-02..2001-09-11 timestamps: !ruby/range 2001-09-03T05:16:23Z..2001-09-04T07:08:13Z
Who knows how useful having other types in your Ranges really is, but it does illustrate the usefulness of YAML.rb's check_implicit, which allows built-in data types to be reparsed in custom types.
Not all languages have built-in regular expression support. But for Ruby, regular expressions are a core object, an essential object!
YAML.rb uses YAML's typing mechanism to support the Regexp class. Regexps are represented as a string using the '!ruby/regexp' type:
starts with a b: !ruby/regexp '/^b/' ends with a z: !ruby/regexp '/z$/' search for a C or c: !ruby/regexp '/c/i'
Regexps also have a to_yaml method, which will type and quote the Regexp for you:
puts( /^b/.to_yaml ) # prints: # --- !ruby/regexp "/^b/"
As mentioned previously, every Ruby object has a to_yaml method which is introduced when YAML.rb is loaded. This method will generated a generic YAML representation of any Ruby object. The 'ruby/object' type will be used, along with the class name and a dump of the public members of the object.
As a simple example, let's suppose you have a Video class, which you are going to use to organize your Important-Enough-to-Write-a-Ruby-Script-for video collection. Here's your prototype class:
class Video attr_accessor :title, :year, :rating def initialize( t, y, r ) @title = t @year = y @rating = r end end
You own two videos, so you create an Array of Videos to represent your video collection.
collection = [ Video.new( "Ishtar", 1987, 8.8 ), Video.new( "Dr. Strangelove", 1964, 10.0 ) ]
When you export the collection to YAML, you'll see each of the videos appear as a '!ruby/object:Video' type:
puts collection.to_yaml # prints: # - !ruby/object:Video # title: Ishtar # year: 1987 # rating: 8.8 # - !ruby/object:Video # title: Dr. Strangelove # year: 1964 # rating: 10.0
You can actually code your own to_yaml method, as YAML.rb has a rather simple API for doing so. It's the same API used to build Yod, the software which generates this documentation.