CSC/ECE 517 Spring 2014/ch1 1w1d mm: Difference between revisions
No edit summary |
No edit summary |
||
Line 291: | Line 291: | ||
| 3 || YAML provides a method [http://www.ruby-doc.org/stdlib-1.9.3/libdoc/syck/rdoc/Object.html (to_yaml_properties)] which can be used to select the variables who's value is need to be serialized. With Marshal, we need to write a method named marshal_dump defining the variables of an object that has to be serialized. || Provides an option for serializing only the required attributes to be serialized for an object. Use the keyword [http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html Transient] to ignore certain data that doesn’t need to be serialized || [http://msdn.microsoft.com/en-us/library/ms973893.aspx XML Serializer] sets [http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributes.xmlignore.aspx XmlIgnoreProperty] to true to ignore the default serialization of a field or a property || Serialization using the Boost libraries is custom and thus the user can specify the part of the objects to be serialized. | | 3 || YAML provides a method [http://www.ruby-doc.org/stdlib-1.9.3/libdoc/syck/rdoc/Object.html (to_yaml_properties)] which can be used to select the variables who's value is need to be serialized. With Marshal, we need to write a method named marshal_dump defining the variables of an object that has to be serialized. || Provides an option for serializing only the required attributes to be serialized for an object. Use the keyword [http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html Transient] to ignore certain data that doesn’t need to be serialized || [http://msdn.microsoft.com/en-us/library/ms973893.aspx XML Serializer] sets [http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributes.xmlignore.aspx XmlIgnoreProperty] to true to ignore the default serialization of a field or a property || Serialization using the Boost libraries is custom and thus the user can specify the part of the objects to be serialized. | ||
|- | |- | ||
| 4 || There are some objects that can not be serialized. These are bindings, procedure objects, singleton objects, instances of IO objects and interfaces. Serializing these objects throws TypeError exceptions. || There are some objects in Java which can not be serialized. These are Thread, OutputStream and its subclasses, and Socket || Objects like DataRow are non serializable in .NET. Whether an object is serializable or not can be checked using the [http://msdn.microsoft.com/en-us/library/system.type.isserializable(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1 Type.IsSerializable] || | | 4 || There are some objects that can not be serialized. These are bindings, procedure objects, singleton objects, instances of IO objects and interfaces. Serializing these objects throws TypeError exceptions. || There are some objects in Java which can not be serialized. These are Thread, OutputStream and its subclasses, and Socket || Objects like DataRow are non serializable in .NET. Whether an object is serializable or not can be checked using the [http://msdn.microsoft.com/en-us/library/system.type.isserializable(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1 Type.IsSerializable] || There are no such objects in C++. | ||
|} | |} | ||
Line 328: | Line 328: | ||
13.[http://ruby.about.com/od/tasks/a/The-Json-Gem.html Installing JSON gem] | 13.[http://ruby.about.com/od/tasks/a/The-Json-Gem.html Installing JSON gem] | ||
14.[http://www.ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html Serialization in Ruby JSON] | |||
15.[http://www.boost.org/doc/libs/1_36_0/libs/serialization/example/demo.cpp Boost Libraries] | |||
16.[http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html Java Serialization] |
Revision as of 01:05, 11 February 2014
Serialization
Serialization[1] is a process of converting a data structure or an object into a stream of bytes or string to facilitate storage in memory, file(persistence storage) or transmission over a network. The process of Serialization is also referred to as Marshalling[2]. 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. Communication between two or more processes on same machine. Object state can be saved and shared in a persistent or in-memory store.
2. Communication between processes on different machines. Serialization facilitates the transmission of an object through a network.
3. Creating a clone of an object.
4. Cross-platform compatibility. Object can be serialized in a common format that is understood by multiple platforms. Eg. JSON, XML.
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.
Few Practical Applications for Serialization
1. HTTP Session Replication by sharing session objects across web servers for handling failover scenarios
2. Serialization facilitates communication in Remote Method Invocation or Remote procedure calls
3. Rails Cookie Handling. Cookies are stored marshalled/unmarshalled to and from client machines.
Serialization in Ruby:
Ruby supplies serialization capabilities through its module, Marshal. There are also some other libraries like YAML and JSON which can be used in Ruby to generate serialization for purposes like platform independence and human readable formats.
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
The conversion of Ruby objects into YAML and JSON formats are explained below.
Converting Ruby Objects to YAML format
YAML[3] format is a human friendly data serialization standard for all programming languages. YAML (YAML Ain't Markup Language) is perhaps the most common form of serialization in Ruby applications. It is used for configuration files in Rails and other projects, and is nearly ubiquitous. YAML is a plaintext format, as opposed to Marshal's[4] binary format. Objects stored as YAML are completely transparent and editable with nothing more than a text editor. It also has a simple, spartan syntax that's easy to look at and easy to type. It is not encumbered by excessive wordage and symbols seen in XML. In order to use it in Ruby, the yaml.rb file is required to be loaded, using the "require" keyword, which provides methods for converting objects into yaml format and creating .yml files.
Examples of serialization using YAML:
#Serialization using YAML's to_yaml method 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 x = First.new("Tom", 25, "USA") puts x puts x.to_yaml
Output:
In First:
Tom, 25, USA
--- !ruby/object:First
name: Tom
age: 25
country: USA
The above code displays the object x, first as a string and then in the yaml format.
Saving YAML data into a file:
# Serialization using YAML::dump require 'yaml' f = File.open( 'first.yml', 'w' ) YAML.dump( ["Tom", 25, "USA"], f ) f.close File.open( 'first.yml' ){ |f| $arr= YAML.load(f) } p( $arr )
Output:
["Tom", 25, "USA"]
The dump function can be used to serialize the data and save it into a file in YAML format. As shown in the above example the data in YAML format can be de-serialized using the load function.
YAML libraries also provides an option of selecting only those variables of the object that are needed to be serialized. This is done using the to_yaml_properties method as shown in the below example.
#Custom Serialization using YAML 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 def to_yaml_properties ["@name","@age"] #@country will not be serialized end end x = First.new("Tom", 25, "USA") puts x puts x.to_yaml
Output:
In First:
Tom, 25, USA
--- !ruby/object:First
name: Tom
age: 25
Converting Ruby Objects to JSON format:
JSON[5] is a light-weight data interchange format. JSON is typically generated by web applications and can be quite daunting, with deep hierarchies that are difficult to navigate. Any Ruby object can easily be serialized into JSON format. On Ruby 1.8.7, you'll need to install a gem. However, in Ruby 1.9.2, the json gem is bundled with the core Ruby distribution. So, if you're using 1.9.2, you're probably all set. If you're on 1.8.7, you'll need to install a gem.[6] The JSON library can be installed using Ruby Gems[7] 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. 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. Binary Serialization is done using Marshal[8] which is built into Ruby and the code for it is written in Ruby's Marshal module(marshal.c) and thus no additional files are required in order to use it. The _dump and _load methods defined in marshal are used for serialization. Although it has some exceptions, as the Marshal module's document says "If the objects to be dumped include bindings, procedure or method objects, instances of class IO, or singleton objects, a TypeError will be raised."
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[9] instead of puts[10] 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.
Binary Serialization Example:
class Animal
def initialize name, age
@name = name
@age=age
end
end
class Cat < Animal
def to_s
"In Cat C: #{@name} \t #{@age}"
end
end
c = Cat.new("Kitty Kat",5)
puts "Before Serialization"
puts c
#puts d
serialize_cat= Marshal.dump(c) #dumps the serialized cat object into serialize_cat
puts "\nAfter Serialization:\n #{serialize_cat}"
deserialize_cat= Marshal::load(serialize_cat) #deserializes the cat object and loads it back into deserialize_cat
puts "\nAfter Deserialization\n #{deserialize_cat}"
Output:
Before Serialization
In Cat C: Kitty Kat 5
After Serialization:
oCat:
@nameI"Kitty Kat:ET: @agei
After Deserialization
In Cat C: Kitty Kat 5
As with the YAML, Marshal can also be used to dump data into a file. The above example showing the serialization using YAML::dump can be written using marshal as shown below.
f = File.open( 'first.yml', 'w' )
Marshal.dump( ["Tom", 25, "USA"], f )
f.close
File.open( 'first.yml' ){ |f|
$arr= Marshal.load(f)
}
p( $arr )
Output:
["Tom", 25, "USA"]
Notice that in the above example there is no "require" statement as opposed to the earlier example of writing serialized data into files using YAML. This is because unlike YAML, marshal is in build in Ruby and no external libraries is required in order to use its functionality.
Marshal can also be used to custom serialize an object i.e. it provides an option to omit the variables of an object that are not required in the serialized data. The following program shows the use of marshal_dump method for achieving custom serialization.
class First
def initialize(name, age, country)
@name = name
@age = age
@country=country
end
def to_s
"In First: #{@name}, #{@age}, #{@country}"
end
def marshal_dump
[@name,@age] #@country will not be serialized
end
def marshal_load(data)
@name=data[0]
@age=data[1]
@country="United States of America"
end
end
x = First.new("Tom", 25, "USA")
puts x
marshal_data = Marshal.dump( x )
y = Marshal.load( marshal_data )
p( y.to_s )
Output:
In First: Tom, 25, USA
"In First: Tom, 25, United States of America"
Serialization in OOLS Languages: Comparison
Sl.No | Ruby | Java | .Net Framework | C++ |
---|---|---|---|---|
1 | Ruby provides a built in module called Marshal for serialization | Java uses an Interface named Serializable interface for classes to implement | .Net provides a Serializable Attribute | Although, there is no built in support for serialization in C++, it can be achieved by using Boost libraries |
2 | The built in module of Ruby (Marshal) does not support platform independence, however, it can be achieved by using external libraries like YAML and JSON | Similarly, Java's built in serialization is also not platform independent and in order to use serialization in Java across Ruby platform, jruby library should be used. | .Net used Remoting technology to make it platform independent. | Serialization using the Boost libraries is not platform independent. |
3 | YAML provides a method (to_yaml_properties) which can be used to select the variables who's value is need to be serialized. With Marshal, we need to write a method named marshal_dump defining the variables of an object that has to be serialized. | Provides an option for serializing only the required attributes to be serialized for an object. Use the keyword Transient to ignore certain data that doesn’t need to be serialized | XML Serializer sets XmlIgnoreProperty to true to ignore the default serialization of a field or a property | Serialization using the Boost libraries is custom and thus the user can specify the part of the objects to be serialized. |
4 | There are some objects that can not be serialized. These are bindings, procedure objects, singleton objects, instances of IO objects and interfaces. Serializing these objects throws TypeError exceptions. | There are some objects in Java which can not be serialized. These are Thread, OutputStream and its subclasses, and Socket | Objects like DataRow are non serializable in .NET. Whether an object is serializable or not can be checked using the Type.IsSerializable | There are no such objects in C++. |
See Also
3. Article on Rails Serialization
References
2. YAML
3. JSON
4. Serializing and De-serializing in Ruby
5. Serialization and De-serialization
6. Marshal
7. Object Serialization Techniques
11.JSON