From 666331731525ba9fcbb0936ca66dc348e10b86b8 Mon Sep 17 00:00:00 2001 From: Cory Monty Date: Wed, 11 May 2011 13:11:54 -0400 Subject: [PATCH 2/2] Adds some basic documentation to JSON module Changes language describing difference between JSON.generate and to_json Adds documentation to JSON classes and methods --- ext/json/generator/generator.c | 1 + ext/json/lib/json.rb | 52 ++++++++++++++++++++++++++++++++++++++++ ext/json/lib/json/add/core.rb | 39 +++++++++++++++++++++++++++--- ext/json/lib/json/common.rb | 6 ++++- 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index fac7abb..ccf614a 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -556,6 +556,7 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) /* * call-seq: to_json(*) * + * Returns a JSON string for nil: 'null'. */ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) { diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb index 789b0de..cc33f72 100644 --- a/ext/json/lib/json.rb +++ b/ext/json/lib/json.rb @@ -1,3 +1,55 @@ +## +# = JavaScript Object Notation (JSON) +# +# JSON is a lightweight data-interchange format. It is easy for us +# humans to read and write. Plus, equally simple for machines to generate or parse. +# JSON is completely language agnostic, making it the ideal interchange format. +# +# Built on two universally available structures: +# 1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array. +# 2. An orderd list of values. More commonly named as an _array_, vector, sequence, or list. +# +# To read more about JSON visit: http://json.org +# +# == Parsing JSON +# +# To parse a JSON string received by another application, or generated within +# your existing application: +# +# require 'json' +# +# my_hash = JSON.parse('{"hello": "goodbye"}') +# puts my_hash["hello"] => "goodbye" +# +# Notice the extra quotes '' around the hash notation. Ruby expects +# the argument to be a string and can't convert objects like a hash or array. +# +# Ruby converts your string into a hash +# +# == Generating JSON +# +# Creating a JSON string for communication or serialization is +# just as simple. +# +# require 'json' +# +# my_hash = {:hello => "goodbye"} +# puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}" +# +# Or an alternative way: +# +# require 'json' +# puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}" +# +# JSON.generate only allows objects or arrays to be converted +# to JSON syntax. While to_json accepts many Ruby classes +# even though it only acts a method for serialization: +# +# require 'json' +# +# 1.to_json => "1" +# + require 'json/common' module JSON require 'json/version' diff --git a/ext/json/lib/json/add/core.rb b/ext/json/lib/json/add/core.rb index 03a00dd..18fd0f3 100644 --- a/ext/json/lib/json/add/core.rb +++ b/ext/json/lib/json/add/core.rb @@ -7,20 +7,26 @@ unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and end require 'date' +# Symbol serialization/deserialization class Symbol + # Stores class name (Symbol) with String representation of Symbol as a JSON string. def to_json(*a) { JSON.create_id => self.class.name, 's' => to_s, }.to_json(*a) end - + + # Deserializes JSON string by converting the string value stored in the object to a Symbol def self.json_create(o) o['s'].to_sym end end +# Time serialization/deserialization class Time + + # Deserializes JSON string by converting time since epoch to Time def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 @@ -31,7 +37,8 @@ class Time at(object['s'], object['n'] / 1000) end end - + + # Stores class name (Time) with number of seconds since epoch and number of microseconds for Time as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -41,13 +48,17 @@ class Time end end +# Date serialization/deserialization class Date + + # Deserializes JSON string by converting Julian year y, month m, day d and Day of Calendar Reform sg to Date. def self.json_create(object) civil(*object.values_at('y', 'm', 'd', 'sg')) end alias start sg unless method_defined?(:start) - + + # Stores class name (Date) with Julian year y, month m, day d and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -59,7 +70,10 @@ class Date end end +# DateTime serialization/deserialization class DateTime + + # Deserializes JSON string by converting year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg to DateTime. def self.json_create(object) args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') of_a, of_b = object['of'].split('/') @@ -73,7 +87,8 @@ class DateTime end alias start sg unless method_defined?(:start) - + + # Stores class name (DateTime) with Julian year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -89,11 +104,15 @@ class DateTime end end +# Range serialization/deserialization class Range + + # Deserializes JSON string by constructing new Range object with arguments a serialized by to_json. def self.json_create(object) new(*object['a']) end + # Stores class name (Range) with JSON array of arguments a which include first (integer), last (integer), and exclude_end? (boolean) as JSON string. def to_json(*args) { JSON.create_id => self.class.name, @@ -102,11 +121,15 @@ class Range end end +# Struct serialization/deserialization class Struct + + # Deserializes JSON string by constructing new Struct object with values v serialized by to_json. def self.json_create(object) new(*object['v']) end + # Stores class name (Struct) with Struct values v as a JSON string. Only named structs are supported. def to_json(*args) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" @@ -117,13 +140,17 @@ class Struct end end +# Exception serialization/deserialization class Exception + + # Deserializes JSON string by constructing new Exception object with message m and backtrace b serialized with to_json def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end + # Stores class name (Exception) with message m and backtrace array b as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -133,11 +160,15 @@ class Exception end end +# Regexp serialization/deserialization class Regexp + + # Deserializes JSON string by constructing new Regexp object with source s (Regexp or String) and options o serialized by to_json def self.json_create(object) new(object['s'], object['o']) end + # Stores class name (Regexp) with options o and source s (Regexp or String) as JSON string def to_json(*) { JSON.create_id => self.class.name, diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index 91cb3c2..7b4b996 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -291,7 +291,8 @@ module JSON recurse_proc(result, &proc) if proc result end - + + # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_ def recurse_proc(result, &proc) case result when Array @@ -342,11 +343,13 @@ module JSON # Shortuct for iconv. if String.method_defined?(:encode) + # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) string.encode(to, from) end else require 'iconv' + # Encodes string using _iconv_ library def self.iconv(to, from, string) Iconv.conv(to, from, string) end @@ -389,6 +392,7 @@ module ::Kernel end end +# Extends any Class to include _json_creatable?_ method. class ::Class # Returns true, if this class can be used to create an instance # from a serialised JSON string. The class has to implement a class -- 1.7.4.1