Ruby objects and JSON serialization (without Rails) Ruby objects and JSON serialization (without Rails) ruby ruby

Ruby objects and JSON serialization (without Rails)


For the JSON library to be available, you may have to install libjson-ruby from your package manager.

To use the 'json' library:

require 'json'

To convert an object to JSON (these 3 ways are equivalent):

JSON.dump object #returns a JSON stringJSON.generate object #returns a JSON stringobject.to_json #returns a JSON string

To convert JSON text to an object (these 2 ways are equivalent):

JSON.load string #returns an objectJSON.parse string #returns an object

It will be a bit more difficult for objects from your own classes. For the following class, to_json will produce something like "\"#<A:0xb76e5728>\"".

class A    def initialize a=[1,2,3], b='hello'        @a = a        @b = b    endend

This probably isn't desirable. To effectively serialise your object as JSON, you should create your own to_json method. To go with this, a from_json class method would be useful. You could extend your class like so:

class A    def to_json        {'a' => @a, 'b' => @b}.to_json    end    def self.from_json string        data = JSON.load string        self.new data['a'], data['b']    endend

You could automate this by inheriting from a 'JSONable' class:

class JSONable    def to_json        hash = {}        self.instance_variables.each do |var|            hash[var] = self.instance_variable_get var        end        hash.to_json    end    def from_json! string        JSON.load(string).each do |var, val|            self.instance_variable_set var, val        end    endend

Then you can use object.to_json to serialise to JSON and object.from_json! string to copy the saved state that was saved as the JSON string to the object.


Check out Oj. There are gotchas when it comes to converting any old object to JSON, but Oj can do it.

require 'oj'class A    def initialize a=[1,2,3], b='hello'        @a = a        @b = b    endenda = A.newputs Oj::dump a, :indent => 2

This outputs:

{  "^o":"A",  "a":[    1,    2,    3  ], "b":"hello"}

Note that ^o is used to designate the object's class, and is there to aid deserialization. To omit ^o, use :compat mode:

puts Oj::dump a, :indent => 2, :mode => :compat

Output:

{  "a":[    1,    2,    3  ],  "b":"hello"}


If rendering performance is critical, you might also want to look at yajl-ruby, which is a binding to the C yajl library. The serialization API for that one looks like:

require 'yajl'Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"