CSC/ECE 517 Fall 2013/ch1 1w05 st
Serialization
Serialization[1] is the process of converting an object or a group of objects into a stream of bytes or string to facilitate storage in memory or transmission over a network. The process of Serialization is also referred to as Marshalling. The stream of data has to be in a format that can be understood by both ends of a communication channel so that the object can be marshaled and reconstructed easily.
Basic Advantages of Serialization:
1.Facilitates the easy transportation of an object through a network.
2.Creates a clone of the object at the receiving end.
3.Ability to transmit data across the network in a cross-platform-compatible format.
4.Saving the data in a persistent or non-persistent storage medium in a non-proprietary format.
De-serialization is the process of converting the stream of bytes or string back to objects in memory. It is the process of reconstructing the object later.This process of de-serialization is also referred to as Unmarshalling.
Serialization in Ruby:
Let us consider a situation where two Ruby programs have to communicate with each other. One of the simplest way to do this is to convert the Ruby objects in the first programs into strings and writing these strings into a file. This is nothing but serialization. The second program can read this file and convert the strings back into Ruby objects. This is de-serialization.
Types of Serialization
Serialization in Ruby can be done in two ways. During serialization, the object in memory can be converted into Human Readable formats like YAML (YAML Ain’t Markup Language) and JSON (JavaScript Object Notation), or the object can be converted into binary format.
Converting Ruby Objects in Human Readable Formats
Converting Ruby Objects to YAML format
YAML[2] format is a human friendly data serialization standard for all programming languages. Any Ruby object can easily be serialized into YAML format. Let us consider the below code,
require "yaml"
class First def initialize(name, age, country) @name = name @age = age @country=country end def to_s "In First:\n#{@name}, #{@age}, #{@country}\n" end end class Second def initialize(address, details) @address = address @details = details end def to_s "In Second:\n#{@details.to_s}#{@address}\n" end end x = First.new("Tom", 25, "USA") y = Second.new("St. Marks Street", x) puts y
We get the string representation of the object tree as the Output (because we have used the function to_s[3]).
Output:
In Second:
In First:
Tom, 25, USA
St. Marks Street
We use the below code to serialize out object tree.
serialized_object = YAML::dump(y)
puts serialized_object
The dump function serializes the object tree and stores the data in the YAML format in the variable serialized_object.
Data in the serialized (YAML) format looks like this:
--- !ruby/object:Second
address: St. Marks Street
details: !ruby/object:First
name: Tom
age: 25
country: USA
Now, to de-serialize the data, we use load function.
puts YAML::load(serialized_object)
The data is converted back to Ruby object tree.
Output:
In Second:
In First:
Tom, 25, USA
St. Marks Street
Thus we get back our original Object tree.
Converting Ruby Objects to JSON format:
JSON[4] is a light-weight data interchange format. Any Ruby object can easily be serialized into JSON format. The JSON library can be installed using Ruby Gems[5] like shown below:
# gem install json
We can create a JSON string for serialization by using the JSON.generate method as below:
require 'json'
my_hash = {:Welcome => "Ruby"}
puts JSON.generate(my_hash) => "{\"WELCOME\":\"RUBY\"}"
Output:
{"{\"Welcome\":\"Ruby\"}"=>"{\"WELCOME\":\"RUBY\"}"}
We can parse the JSON string received from another program by using JSON.parse Ruby thus converts String to Hash.
require 'json'
my_hash = JSON.parse('{"Welcome": "Ruby"}')
puts my_hash["Welcome"] => "Ruby"
Converting Ruby Objects to Binary Formats
Binary Serialization is another form of serialization in Ruby which is not in human readable form. It is similar to YAML Serialization. Binary Serialization is done using Marshal. Binary Serialization is used when high performance serialization and de-serialization process is required and when the contents are not required to be in readable format.
Since the Binary Serialized data is not in human readable form, there are two essential guidelines that need to be followed. They are :
1.Use print instead of puts when serialized objects are written to a file in order to avoid new line characters to be written in the file. 2.Use a record separator in order to differentiate between two objects.
class Animal
def initialize name, age
@name = name
@age=age
puts "#{self.class.name}"
end
end
class Cat < Animal
def to_s
"In Cat C: #{@name} \t #{@age}"
end
end
class Dog < Animal
def to_s
puts "In Dog D: #{@name} \t #{@age}"
end
end
d = Dog.new("Doggy Dig", 4)
c = Cat.new("Kitty Kat",5)
puts "Before Serialization"
puts c
puts d
serialize_cat= Marshal.dump(c)
serialize_dog= Marshal.dump(d)
deserialize_cat= Marshal::load(serialize_cat)
deserialize_dog= Marshal::load(serialize_dog)
puts "After Serialization #{deserialize_cat}"
puts "After Dog Serialization #{deserialize_dog}"
References
5. http://www.skorks.com/2010/04/serializing-and-deserializing-objects-with-ruby/
6. http://www.codeproject.com/Articles/33296/Serialization-and-De-serialization