Serialization

How to turn your 3-D objects into nice linear strings, ready for transport to the Interwebs.

Scroll down...

Content

Resources

Comments

You've learned all about Ruby objects. Now, it's time to think about how to send those objects to other files, programs or even the Web. The key to everything is strings.

Behind the scenes, everything on your computer, a server, or in web browsers is being transmitted using "streams" of bytes. When a program reads or writes, it processes the stream one byte at a time until it reaches the "end of file (EOF)" marker or some other stop point.

A file itself is really just a big string of bytes (usually characters), as you'll shortly see. When a web server sends a response to your browser, it does so by sending one long string using HTTP. So strings are everywhere when we talk about the reading, writing, and transmission of data.

Strings are useful for programs behind the scenes, but you'd much rather work with objects. How do you convert an object, e.g. a Ruby hash or instance, into a string so it can be saved or sent across the web? How do you then parse that string on the other end?

This is the idea behind "serializing" objects into strings and then "deserializing" them back into objects. In this lesson, we'll briefly cover the methods you can use to accomplish this so you'll be comfortable working with serialized objects. Upcoming lessons will discuss different ways of parsing, saving, and transmitting the resulting strings.

What is Serialization?

Serialization itself is a simple concept -- turn a "3-D" object into a single long string. For example, turning this:

{:name => "Dolph", :age => 21}

...into something like this:

"---\n:name: Dolph\n:age: 21\n"

Why Use Serialization?

Serialization is very useful whether you're thinking of saving your objects and classes (like when you're in the middle of a game) to a file or when you're transmitting those same types of objects to the web browser (since the only way for information to travel via HTTP is as a string).

Essentially, once your data is a string, you can send it or save it pretty much anywhere. You'll learn more about using files in the upcoming lesson.

Serialization Formats

You know from previous lessons that an HTML file is sent to the browser as one giant string... all the tags are just represented in one long list. If the markup tags can be represented using a string, it should make sense that any of your Ruby objects can be represented in a similar fashion.

The most common formats for serializing Ruby objects are JSON, YAML and XML. Each of these follows a slightly different convention but, for your purposes, it usually doesn't actually matter which one you use. That's because you'll typically rely on pre-made scripts to do the serializing and de-serializing anyway.

YAML

YAML (YAML Markup Language (yes, it's recursive)) is an all-purpose human-friendly data serialization standard. So, basically, you can convert your objects to it and it's easy to read. It's sometimes used for configuration files (like in Rails) so you can edit them manually but they are still machine readable.

YAML relies on dashes, newlines, and spacing to determine your file composition. As we said, don't worry about memorizing the format, but it's interesting to see how it looks:

# in Ruby
{ 'foo' => 'whatever',  
  'bar' => [ 
    { 
        'fruit' => 'apple',  
        'name' => 'steve', 
        'sport' => 'baseball' 
    }, 
    'a_flat_item', 
    { 
      'python' => 'rocks', 
      'perl' => 'papers', 
      'ruby' => 'scissorseseses' 
    } 
  ] 
}

# in YAML
foo: whatever 
bar: 
 - 
   fruit: apple 
   name: steve 
   sport: baseball 
 - a_flat_item 
 - 
   python: rocks 
   perl: papers 
   ruby: scissorseseses 

Serializing with YAML

The YAML gem is already a part of Ruby's standard library so you don't even need to install it. To use it, require the 'yaml' library and make use of its load and to_yaml or dump functions:

> require 'yaml'
#=> true

# 2 methods to turn the object into YAML:
> dump = YAML::dump({:name => "Dolph", :age => 21}) # Method 1
#=> "---\n:name: Dolph\n:age: 21\n" 
> dump = {:name => "Dolph", :age => 21}.to_yaml # Method 2
#=> "---\n:name: Dolph\n:age: 21\n"

# Now you can save that to a file or send over the web

> our_hash = YAML::load(dump)
#=> {:name=>"Dolph", :age=>21}

Note that the :: notation is just to indicate that we're calling a class method on the YAML class and is the same as if you'd used a normal period .

JSON

JSON (JavaScript Object Notation) is frequently used to send files across the web. You'll see it often in Rails and when you interface with external APIs over the web that need to return deeply nested data like Google Maps.

Here's a look at the format:

# in Ruby
{:name=>"Dolph", :age=>21}

# in JSON
"{\"name\":\"Dolph\",\"age\":21}"

Serializing with JSON

It's also quite easy to use in Ruby. You need to install the gem and use it in a similar fashion to YAML. There are also several identical ways to "JSON-ify" an object:

$ gem install json

# IRB
> require 'json'
# Two methods for converting an object to JSON:
> my_json = {:name=>"Dolph", :age=>21}.to_json # Method 1
#=> "{\"name\":\"Dolph\",\"age\":21}" 
> my_json = JSON.dump({:name=>"Dolph", :age=>21}) # Method 2
#=> "{\"name\":\"Dolph\",\"age\":21}" 
# To parse a JSON string back into a Ruby object:
> JSON.parse(my_json)
#=> {"name"=>"Dolph", "age"=>21}

XML

You may not see XML as often in the Rails world but it's still used all over the place for structured data storage elsewhere. It's also a highly customizable format that allows you to specify exactly how you want your data stored. Because of this, you're more likely to find custom XML serializers and de-serializers in any given application than a standard library.

You can safely stick to YAML and JSON for now for your Ruby objects, though it's worth noting that HTML is really just XML so your browser is going through a lot of XML parsing in the background as well.

Code Review

The important bits of code from this lesson

# Require YAML
require `yaml`

# Serialize to YAML
serialized_obj = {:name => "Dolph", :age => 21}.to_yaml

# De-serialize from YAML
YAML::load(serialized_obj)

# Enabling JSON
$ gem install json
require 'json'

# Serialize to JSON
my_json = {:name=>"Dolph", :age=>21}.to_json

# Deserialize from JSON
JSON.parse(my_json)

Wrapping Up

Serialization is pretty simple stuff that you'll run into all over the place. In the next few lessons, we'll look specifically at how to take advantage of it to work with files on your hard drive and parse the results.



Sign up to track your progress for free

There are ( ) additional resources for this lesson. Check them out!

Sorry, comments aren't active just yet!

Next Lesson: File I/O Basics