FIRM - Format Independent Ruby Marshalling
Introduction
FIRM is a pure Ruby library that works across different Ruby implementations like MRI Ruby and JRuby providing format independent object (de-)serialization support.
FIRM is explicitly NOT intended as a non-discriminative marshaling library (dumping any object's attributes) but rather as a structured and safe serialization library requiring users to think about what state they want persisted (and possibly in what form) and what not. Straightforward attribute serialization is simple with minimal intrusion on user code. In addition various customization options are available to tweak (de-)serialization for a perfect fit if needed.
Out of the box (de-)serializing Ruby objects to(from) JSON and YAML is supported without any additional
dependencies.
When the nokogiri
gem is installed (and loaded before FIRM) XML (de-)serializing will also be available.
FIRM supports (de-)serializing many core Ruby objects out of the box including:
NilClass
-
TrueClass
&FalseClass
Integer
Float
Rational
Complex
-
BigDecimal
(if loaded; not default anymore starting from Ruby 3.4) String
Symbol
Array
Hash
Range
Regexp
Time
Struct
Set
-
OpenStruct
(optional starting from Ruby 3.5 which removes this class from the standard library) Date
DateTime
For simplicity and security reasons FIRM does not support direct (de-)serializing of Class
objects but will rather
serialize (and deserialize) these as their scoped string names. Customized property setters can be used to
resolve Class objects from these names if really needed.
Serialization support for user defined classes is available through a simple DSL scheme.
FIRM provides object aliasing support for JSON and XML in a similar fashion as the standard support provided
by YAML.
In addition FIRM automatically recognizes and handles cyclic references of aliasable objects.
FIRM serialization is also thread safe and supports re-entrancy (i.e. nested serialization).
Installing FIRM
FIRM is distributed as a Ruby gem on RubyGems. This gem can also be downloaded from the release assets on Github.
Installing the gem requires no additional installation steps and/or additional software to be installed except for a supported version of the Ruby interpreter. So the following command is all it takes to install:
gem install firm
Installing the nokogiri
gem is optional to enable the XML serialization format.
Usage examples
Serialize an array of objects to JSON string
ruby
require 'firm'
a = [1, '2', :three, 4.321]
json = a.serialize
FIRM.deserialize(json)
IRB output:
=> true
=>
[1,
"2",
:three,
4.321]
=> "[1,\"2\",{\"json_class\":\"Symbol\",\"s\":\"three\"},4.321]"
=>
[1,
"2",
:three,
4.321]
Alternatively the object can be serialized to the YAML or XML (if the nokogiri
gem is installed) format like this.
require 'firm'
a = [1, '2', :three, 4.321]
json = a.serialize(format: :yaml)
FIRM.deserialize(json, format: :yaml)
IRB output:
=> true
=>
[1,
"2",
:three,
4.321]
=> "---\n- 1\n- '2'\n- :three\n- 4.321\n"
=>
[1,
"2",
:three,
4.321]
Serialize a user defined object
require 'nokogiri' # enable XML output format
require 'firm'
class Point
# define the class as serializable
include FIRM::Serializable
# declare the serializable properties of instances of this class
properties :x, :y
# allow instantiation using the default ctor (no args)
# (custom creation schemes can be defined)
def initialize(*args)
if args.empty?
@x = @y = 0
else
@x, @y = *args
end
end
# define the default getter/setter support FIRM will use when (de-)serializing properties
# (customization options are available)
attr_accessor :x, :y
end
rect = {topleft: Point.new(1,1), bottomright: Point.new(32, 64)}
xml = rect.serialize(format: :xml)
# all serializable classes provide the #deserialize class method
Hash.deserialize(xml, format: :xml)
IRB output:
=> true
=> true
=>
[:x,
:x=,
:y,
:y=]
=>
{:topleft=>
#<Point:0x00007f6da9902518
@x=
1,
@y=
1>,
:bottomright=>
#<Point:0x00007f6da9902450
@x=
32,
@y=
64>}
=> "<?xml version=\"1.0\"?>\n<Hash><P><Symbol>topleft</Symbol><Object class=\"Point\"><x><Integer>1</Integer></x><y><Integer>1</Integer></y></Object></P><P><Symbol>bottomright</Symbol><Object class=\"Point\"><x><Integer>32</Integer></x><y><Integer>64</Integer></y></Object></P></Hash>\n"
=> nil
=>
{:topleft=>
#<Point:0x00007f6da98f2208
@x=
1,
@y=
1>,
:bottomright=>
#<Point:0x00007f6da98f0d90
@x=
32,
@y=
64>}
See USAGE for more information.
FIRM licence
FIRM is free and open-source. It is distributed under the liberal MIT licence which is compatible with both free and commercial development. See LICENSE for more details.
Required Credits and Attribution
FIRM requires no attribution, beyond retaining existing copyright notices.