Module: JSON
| Relationships & Source Files | |
| Namespace Children | |
| Modules: | |
| Classes: | |
| Exceptions: | |
| Defined in: | ext/json/lib/json.rb, ext/json/generator/generator.c, ext/json/lib/json/common.rb, ext/json/lib/json/ext.rb, ext/json/lib/json/generic_object.rb, ext/json/lib/json/version.rb, ext/json/lib/json/ext/generator/state.rb, ext/json/parser/parser.c | 
Overview
JavaScript Object Notation (JSON)
JSON is a lightweight data-interchange format.
A JSON value is one of the following:
- 
Double-quoted text: "foo".
- 
Number: 1,1.0,2.0e2.
- 
Boolean: true,false.
- 
Null: null.
- 
Array: an ordered list of values, enclosed by square brackets: ["foo", 1, 1.0, 2.0e2, true, false, null]
- 
Object: a collection of name/value pairs, enclosed by curly braces; each name is double-quoted text; the values may be any JSON values: {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
A JSON array or object may contain nested arrays, objects, and scalars to any depth:
{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
[{"foo": 0, "bar": 1}, ["baz", 2]]Using Module JSON
To make module JSON available in your code, begin with:
require 'json'All examples here assume that this has been done.
Parsing JSON
You can parse a String containing JSON data using either of two methods:
- 
JSON.parse(source, opts)
- 
JSON.parse!(source, opts)
where
- 
sourceis a Ruby object.
- 
optsis a Hash object containing options that control both input allowed and output formatting.
The difference between the two methods is that .parse! omits some checks and may not be safe for some source data; use it only for data from trusted sources. Use the safer method .parse for less trusted sources.
Parsing JSON Arrays
When source is a JSON array, .parse by default returns a Ruby Array:
json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
ruby = JSON.parse(json)
ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
ruby.class # => ArrayThe JSON array may contain nested arrays, objects, and scalars to any depth:
json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]Parsing JSON Objects
When the source is a JSON object, .parse by default returns a Ruby Hash:
json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
ruby = JSON.parse(json)
ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
ruby.class # => HashThe JSON object may contain nested arrays, objects, and scalars to any depth:
json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}Parsing JSON Scalars
When the source is a JSON scalar (not an array or object), .parse returns a Ruby scalar.
String:
ruby = JSON.parse('"foo"')
ruby # => 'foo'
ruby.class # => StringInteger:
ruby = JSON.parse('1')
ruby # => 1
ruby.class # => IntegerFloat:
ruby = JSON.parse('1.0')
ruby # => 1.0
ruby.class # => Float
ruby = JSON.parse('2.0e2')
ruby # => 200
ruby.class # => FloatBoolean:
ruby = JSON.parse('true')
ruby # => true
ruby.class # => TrueClass
ruby = JSON.parse('false')
ruby # => false
ruby.class # => FalseClassNull:
ruby = JSON.parse('null')
ruby # => nil
ruby.class # => NilClassParsing Options
Input Options
Option max_nesting (Integer) specifies the maximum nesting depth allowed; defaults to 100; specify false to disable depth checking.
With the default, false:
source = '[0, [1, [2, [3]]]]'
ruby = JSON.parse(source)
ruby # => [0, [1, [2, [3]]]]Too deep:
# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.parse(source, {max_nesting: 1})Bad value:
# Raises TypeError (wrong argument type Symbol (expected Fixnum)):
JSON.parse(source, {max_nesting: :foo})Option allow_nan (boolean) specifies whether to allow NaN, Infinity, and MinusInfinity in source; defaults to false.
With the default, false:
# Raises JSON::ParserError (225: unexpected token at '[NaN]'):
JSON.parse('[NaN]')
# Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
JSON.parse('[Infinity]')
# Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
JSON.parse('[-Infinity]')Allow:
source = '[NaN, Infinity, -Infinity]'
ruby = JSON.parse(source, {allow_nan: true})
ruby # => [NaN, Infinity, -Infinity]Output Options
Option symbolize_names (boolean) specifies whether returned Hash keys should be Symbols; defaults to false (use Strings).
With the default, false:
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}Use Symbols:
ruby = JSON.parse(source, {symbolize_names: true})
ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}Option object_class (Class) specifies the Ruby class to be used for each JSON object; defaults to Hash.
With the default, Hash:
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby.class # => HashUse class OpenStruct:
ruby = JSON.parse(source, {object_class: OpenStruct})
ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>Option array_class (Class) specifies the Ruby class to be used for each JSON array; defaults to Array.
With the default, Array:
source = '["foo", 1.0, true, false, null]'
ruby = JSON.parse(source)
ruby.class # => ArrayUse class Set:
ruby = JSON.parse(source, {array_class: Set})
ruby # => #<Set: {"foo", 1.0, true, false, nil}>Option create_additions (boolean) specifies whether to use JSON additions in parsing. See \ Additions.
Generating JSON
To generate a Ruby String containing JSON data, use method JSON.generate(source, opts), where
- 
sourceis a Ruby object.
- 
optsis a Hash object containing options that control both input allowed and output formatting.
Generating JSON from Arrays
When the source is a Ruby Array, .generate returns a String containing a JSON array:
ruby = [0, 's', :foo]
json = JSON.generate(ruby)
json # => '[0,"s","foo"]'The Ruby Array array may contain nested arrays, hashes, and scalars to any depth:
ruby = [0, [1, 2], {foo: 3, bar: 4}]
json = JSON.generate(ruby)
json # => '[0,[1,2],{"foo":3,"bar":4}]'Generating JSON from Hashes
When the source is a Ruby Hash, .generate returns a String containing a JSON object:
ruby = {foo: 0, bar: 's', baz: :bat}
json = JSON.generate(ruby)
json # => '{"foo":0,"bar":"s","baz":"bat"}'The Ruby Hash array may contain nested arrays, hashes, and scalars to any depth:
ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
json = JSON.generate(ruby)
json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'Generating JSON from Other Objects
When the source is neither an Array nor a Hash, the generated JSON data depends on the class of the source.
When the source is a Ruby Integer or Float, .generate returns a String containing a JSON number:
JSON.generate(42) # => '42'
JSON.generate(0.42) # => '0.42'When the source is a Ruby String, .generate returns a String containing a JSON string (with double-quotes):
JSON.generate('A string') # => '"A string"'When the source is true, false or nil, .generate returns a String containing the corresponding JSON token:
JSON.generate(true) # => 'true'
JSON.generate(false) # => 'false'
JSON.generate(nil) # => 'null'When the source is none of the above, .generate returns a String containing a JSON string representation of the source:
JSON.generate(:foo) # => '"foo"'
JSON.generate(Complex(0, 0)) # => '"0+0i"'
JSON.generate(Dir.new('.')) # => '"#<Dir>"'Generating Options
Input Options
Option allow_nan (boolean) specifies whether NaN, Infinity, and -Infinity may be generated; defaults to false.
With the default, false:
# Raises JSON::GeneratorError (920: NaN not allowed in JSON):
JSON.generate(JSON::NaN)
# Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
JSON.generate(JSON::Infinity)
# Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
JSON.generate(JSON::MinusInfinity)Allow:
ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'Option max_nesting (Integer) specifies the maximum nesting depth in obj; defaults to 100.
With the default, 100:
obj = [[[[[[0]]]]]]
JSON.generate(obj) # => '[[[[[[0]]]]]]'Too deep:
# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.generate(obj, max_nesting: 2)Escaping Options
Options script_safe (boolean) specifies wether '\u2028', '\u2029' and '/' should be escaped as to make the JSON object safe to interpolate in script tags.
Options ascii_only (boolean) specifies wether all characters outside the ASCII range should be escaped.
Output Options
The default formatting options generate the most compact JSON data, all on one line and with no whitespace.
You can use these formatting options to generate JSON data in a more open format, using whitespace. See also .pretty_generate.
- 
Option array_nl(String) specifies a string (usually a newline) to be inserted after each JSON array; defaults to the empty String,''.
- 
Option object_nl(String) specifies a string (usually a newline) to be inserted after each JSON object; defaults to the empty String,''.
- 
Option indent(String) specifies the string (usually spaces) to be used for indentation; defaults to the empty String,''; defaults to the empty String,''; has no effect unless optionsarray_nlorobject_nlspecify newlines.
- 
Option space(String) specifies a string (usually a space) to be inserted after the colon in each JSON object’s pair; defaults to the empty String,''.
- 
Option space_before(String) specifies a string (usually a space) to be inserted before the colon in each JSON object’s pair; defaults to the empty String,''.
In this example, obj is used first to generate the shortest JSON data (no whitespace), then again with all formatting options specified:
obj = {foo: [:, :baz], bat: {bam: 0, bad: 1}}
json = JSON.generate(obj)
puts 'Compact:', json
opts = {
  array_nl: "\n",
  object_nl: "\n",
  indent: '  ',
  space_before: ' ',
  space: ' '
}
puts 'Open:', JSON.generate(obj, opts)Output:
Compact:
{"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
Open:
{
  "foo" : [
    "bar",
    "baz"
],
  "bat" : {
    "bam" : 0,
    "bad" : 1
  }
}JSON Additions
When you “round trip” a non-String object from Ruby to JSON and back, you have a new String, instead of the object you began with:
ruby0 = Range.new(0, 2)
json = JSON.generate(ruby0)
json # => '0..2"'
ruby1 = JSON.parse(json)
ruby1 # => '0..2'
ruby1.class # => StringYou can use JSON additions to preserve the original object. The addition is an extension of a ruby class, so that:
- 
JSON.generate stores more information in the JSON string. 
- 
JSON.parse, called with option create_additions, uses that information to create a proper Ruby object.
This example shows a Range being generated into JSON and parsed back into Ruby, both without and with the addition for Range:
ruby = Range.new(0, 2)
# This passage does not use the addition for Range.
json0 = JSON.generate(ruby)
ruby0 = JSON.parse(json0)
# This passage uses the addition for Range.
require 'json/add/range'
json1 = JSON.generate(ruby)
ruby1 = JSON.parse(json1, create_additions: true)
# Make a nice display.
display = <<~EOT
  Generated JSON:
    Without addition:  #{json0} (#{json0.class})
    With addition:     #{json1} (#{json1.class})
  Parsed JSON:
    Without addition:  #{ruby0.inspect} (#{ruby0.class})
    With addition:     #{ruby1.inspect} (#{ruby1.class})
EOT
puts displayThis output shows the different results:
Generated JSON:
  Without addition:  "0..2" (String)
  With addition:     {"json_class":"Range","a":[0,2,false]} (String)
Parsed JSON:
  Without addition:  "0..2" (String)
  With addition:     0..2 (Range)The JSON module includes additions for certain classes. You can also craft custom additions. See Custom \ Additions.
Built-in Additions
The JSON module includes additions for certain classes. To use an addition, require its source:
- 
BigDecimal: require 'json/add/bigdecimal'
- 
Complex: require 'json/add/complex'
- 
Date: require 'json/add/date'
- 
DateTime: require 'json/add/date_time'
- 
Exception: require 'json/add/exception'
- 
OpenStruct: require 'json/add/ostruct'
- 
Range: require 'json/add/range'
- 
Rational: require 'json/add/rational'
- 
Regexp: require 'json/add/regexp'
- 
Set: require 'json/add/set'
- 
Struct: require 'json/add/struct'
- 
Symbol: require 'json/add/symbol'
- 
Time: require 'json/add/time'
To reduce punctuation clutter, the examples below show the generated JSON via puts, rather than the usual inspect,
BigDecimal:
require 'json/add/bigdecimal'
ruby0 = BigDecimal(0) # 0.0
json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
ruby1 = JSON.parse(json, create_additions: true) # 0.0
ruby1.class # => BigDecimalComplex:
require 'json/add/complex'
ruby0 = Complex(1+0i) # 1+0i
json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
ruby1 = JSON.parse(json, create_additions: true) # 1+0i
ruby1.class # ComplexDate:
require 'json/add/date'
ruby0 = Date.today # 2020-05-02
json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
ruby1.class # DateDateTime:
require 'json/add/date_time'
ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
ruby1.class # DateTimeException (and its subclasses including RuntimeError):
require 'json/add/exception'
ruby0 = Exception.new('A message') # A message
json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # A message
ruby1.class # Exception
ruby0 = RuntimeError.new('Another message') # Another message
json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # Another message
ruby1.class # RuntimeErrorOpenStruct:
require 'json/add/ostruct'
ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
ruby1.class # OpenStructRange:
require 'json/add/range'
ruby0 = Range.new(0, 2) # 0..2
json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
ruby1 = JSON.parse(json, create_additions: true) # 0..2
ruby1.class # RangeRational:
require 'json/add/rational'
ruby0 = Rational(1, 3) # 1/3
json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
ruby1 = JSON.parse(json, create_additions: true) # 1/3
ruby1.class # RationalRegexp:
require 'json/add/regexp'
ruby0 = Regexp.new('foo') # (?-mix:foo)
json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
ruby1.class # RegexpSet:
require 'json/add/set'
ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
ruby1.class # SetStruct:
require 'json/add/struct'
Customer = Struct.new(:name, :address) # Customer
ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
ruby1.class # CustomerSymbol:
require 'json/add/symbol'
ruby0 = :foo # foo
json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # foo
ruby1.class # SymbolTime:
require 'json/add/time'
ruby0 = Time.now # 2020-05-02 11:28:26 -0500
json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
ruby1.class # TimeCustom JSON Additions
In addition to the JSON additions provided, you can craft JSON additions of your own, either for Ruby built-in classes or for user-defined classes.
Here’s a user-defined class Foo:
class Foo
  attr_accessor :, :baz
  def initialize(, baz)
    self. = 
    self.baz = baz
  end
endHere’s the JSON addition for it:
# Extend class Foo with JSON addition.
class Foo
  # Serialize Foo object with its class name and arguments
  def to_json(*args)
    {
      JSON.create_id  => self.class.name,
      'a'             => [ , baz ]
    }.to_json(*args)
  end
  # Deserialize JSON string by constructing new Foo object with arguments.
  def self.json_create(object)
    new(*object['a'])
  end
endDemonstration:
require 'json'
# This Foo object has no custom addition.
foo0 = Foo.new(0, 1)
json0 = JSON.generate(foo0)
obj0 = JSON.parse(json0)
# Lood the custom addition.
require_relative 'foo_addition'
# This foo has the custom addition.
foo1 = Foo.new(0, 1)
json1 = JSON.generate(foo1)
obj1 = JSON.parse(json1, create_additions: true)
#   Make a nice display.
display = <<~EOT
  Generated JSON:
    Without custom addition:  #{json0} (#{json0.class})
    With custom addition:     #{json1} (#{json1.class})
  Parsed JSON:
    Without custom addition:  #{obj0.inspect} (#{obj0.class})
    With custom addition:     #{obj1.inspect} (#{obj1.class})
EOT
puts displayOutput:
Generated JSON:
  Without custom addition:  "#<Foo:0x0000000006534e80>" (String)
  With custom addition:     {"json_class":"Foo","a":[0,1]} (String)
Parsed JSON:
  Without custom addition:  "#<Foo:0x0000000006534e80>" (String)
  With custom addition:     #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)Constant Summary
- 
    Infinity =
    
 # File 'ext/json/lib/json/common.rb', line 1211.0/0 
- 
    JSON_LOADED =
    
 # File 'ext/json/lib/json/ext.rb', line 22true
- 
    MinusInfinity =
    
 # File 'ext/json/lib/json/common.rb', line 123-Infinity 
- 
    NOT_SET =
    private
    
 # File 'ext/json/lib/json/common.rb', line 8Object.new.freeze 
- 
    NaN =
    
 # File 'ext/json/lib/json/common.rb', line 1190.0/0 
- 
    UnparserError =
    Internal use only
    # File 'ext/json/lib/json/common.rb', line 164For backwards compatibility GeneratorError
- 
    VERSION =
    
 # File 'ext/json/lib/json/version.rb', line 4'2.9.1'
Class Attribute Summary
- 
    
      .create_id  
    
    rw
    Returns the current create identifier. 
- 
    
      .create_id=(new_value)  
    
    rw
    Sets create identifier, which is used to decide if the json_create hook of a class should be called; initial value is json_class:
- 
    
      .dump_default_options  
    
    rw
    Sets or returns the default options for the .dump method. 
- 
    
      .generator  
    
    rw
    Returns the JSONgenerator module that is used byJSON.
- 
    
      .load_default_options  
    
    rw
    Sets or returns default options for the .load method. 
- 
    
      .parser  
    
    rw
    Returns the JSONparser class that is used byJSON.
- 
    
      .state  
    
    rw
    Sets or Returns the JSONgenerator state class that is used byJSON.
- 
    
      .unsafe_load_default_options  
    
    rw
    Sets or returns default options for the .unsafe_load method. 
- 
    
      .generator=(generator)  
    
    rw
    Internal use only
    ::Setthe module generator to be used byJSON.
- 
    
      .parser=(parser)  
    
    rw
    Internal use only
    ::SettheJSONparser class parser to be used byJSON.
Class Method Summary
- .[](object) ⇒ Array, String
- .create_fast_state
- .create_pretty_state
- 
    
      .iconv(to, from, string)  
    
    Encodes string using String.encode.
- 
    
      .dump(obj, io = nil, limit = nil)  
    
    mod_func
    Dumps objas a JSON string, i.e. calls generate on the object and returns the result.
- 
    
      .fast_generate(obj, opts)  ⇒ String 
      (also: .fast_unparse)
    
    mod_func
    Arguments objandoptshere are the same as argumentsobjandoptsin .generate.
- .fast_unparse mod_func
- 
    
      .generate(obj, opts = nil)  ⇒ String 
      (also: .unparse)
    
    mod_func
    Returns a String containing the generated JSON data. 
- 
    
      .load(source, proc = nil, options = {})  ⇒ Object 
      (also: .restore)
    
    mod_func
    Returns the Ruby objects created by parsing the given source.
- 
    
      .load_file(path, opts = {})  ⇒ Object 
    
    mod_func
    Calls: 
- 
    
      .load_file!(path, opts = {})  
    
    mod_func
    Calls: 
- .merge_dump_options(opts, strict: NOT_SET) mod_func
- 
    
      .parse(source, opts)  ⇒ Object 
    
    mod_func
    Returns the Ruby objects created by parsing the given source.
- 
    
      .parse!(source, opts)  ⇒ Object 
    
    mod_func
    Calls. 
- 
    
      .pretty_generate(obj, opts = nil)  ⇒ String 
      (also: .pretty_unparse)
    
    mod_func
    Arguments objandoptshere are the same as argumentsobjandoptsin .generate.
- .pretty_unparse mod_func
- .restore mod_func
- .unparse mod_func
- 
    
      .unsafe_load(source, proc = nil, options = {})  ⇒ Object 
    
    mod_func
    Returns the Ruby objects created by parsing the given source.
- 
    
      .deep_const_get(path)  
    
    Internal use only
    Return the constant located at path. 
- 
    
      .recurse_proc(result, &proc)  
    
    mod_func
    Internal use only
    Recursively calls passed Proc if the parsed data structure is an Array or Hash. 
Class Attribute Details
.create_id (rw)
Returns the current create identifier. See also .create_id=.
# File 'ext/json/lib/json/common.rb', line 115
def self.create_id Thread.current[:"JSON.create_id"] || 'json_class' end
.create_id=(new_value) (rw)
Sets create identifier, which is used to decide if the json_create hook of a class should be called; initial value is json_class:
JSON.create_id # => 'json_class'# File 'ext/json/lib/json/common.rb', line 109
def self.create_id=(new_value) Thread.current[:"JSON.create_id"] = new_value.dup.freeze end
.dump_default_options (rw)
Sets or returns the default options for the .dump method. Initially:
opts = JSON.
opts # => {:max_nesting=>false, :allow_nan=>true}# File 'ext/json/lib/json/common.rb', line 761
attr_accessor :
.generator (rw)
Returns the JSON generator module that is used by JSON.
# File 'ext/json/lib/json/common.rb', line 100
attr_reader :generator
.generator=(generator) (rw)
::Set the module generator to be used by JSON.
# File 'ext/json/lib/json/common.rb', line 57
def generator=(generator) # :nodoc: old, $VERBOSE = $VERBOSE, nil @generator = generator generator_methods = generator::GeneratorMethods for const in generator_methods.constants klass = const_get(const) modul = generator_methods.const_get(const) klass.class_eval do instance_methods(false).each do |m| m.to_s == 'to_json' and remove_method m end include modul end end self.state = generator::State const_set :State, self.state const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby const_set :FAST_STATE_PROTOTYPE, create_fast_state const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state ensure $VERBOSE = old end
.load_default_options (rw)
Sets or returns default options for the .load method. Initially:
opts = JSON.
opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}# File 'ext/json/lib/json/common.rb', line 418
attr_accessor :
.parser (rw)
Returns the JSON parser class that is used by JSON.
# File 'ext/json/lib/json/common.rb', line 37
attr_reader :parser
.parser=(parser) (rw)
::Set the JSON parser class parser to be used by JSON.
.state (rw)
Sets or Returns the JSON generator state class that is used by JSON.
# File 'ext/json/lib/json/common.rb', line 103
attr_accessor :state
.unsafe_load_default_options (rw)
Sets or returns default options for the .unsafe_load method. Initially:
opts = JSON.
opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}# File 'ext/json/lib/json/common.rb', line 404
attr_accessor :
Class Method Details
    .[](object)  ⇒ Array, String   
.create_fast_state
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 80
def create_fast_state State.new( :indent => '', :space => '', :object_nl => "", :array_nl => "", :max_nesting => false ) end
.create_pretty_state
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 90
def create_pretty_state State.new( :indent => ' ', :space => ' ', :object_nl => "\n", :array_nl => "\n" ) end
.deep_const_get(path)
Return the constant located at path. The format of path has to be either ::A::B::C or A::B::C. In any case, A has to be located at the top level (absolute namespace path?). If there doesn’t exist a constant at the given path, an ArgumentError is raised.
# File 'ext/json/lib/json/common.rb', line 50
def deep_const_get(path) # :nodoc: Object.const_get(path) rescue NameError => e raise ArgumentError, "can't get const #{path}: #{e}" end
.dump(obj, io = nil, limit = nil) (mod_func)
Dumps obj as a JSON string, i.e. calls generate on the object and returns the result.
The default options can be changed via method .dump_default_options.
- 
Argument io, if given, should respond to methodwrite; the JSON String is written toio, andiois returned. Ifiois not given, the JSON String is returned.
- 
Argument limit, if given, is passed to .generate as optionmax_nesting.
When argument io is not given, returns the JSON String generated from obj:
obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
json = JSON.dump(obj)
json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}"When argument io is given, writes the JSON String to io and returns io:
path = 't.json'
File.open(path, 'w') do |file|
  JSON.dump(obj, file)
end # => #<File:t.json (closed)>
puts File.read(path)Output:
{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}# File 'ext/json/lib/json/common.rb', line 795
def dump(obj, anIO = nil, limit = nil, kwargs = nil) if kwargs.nil? if limit.nil? if anIO.is_a?(Hash) kwargs = anIO anIO = nil end elsif limit.is_a?(Hash) kwargs = limit limit = nil end end unless anIO.nil? if anIO.respond_to?(:to_io) anIO = anIO.to_io elsif limit.nil? && !anIO.respond_to?(:write) anIO, limit = nil, anIO end end opts = JSON. opts = opts.merge(:max_nesting => limit) if limit opts = (opts, **kwargs) if kwargs begin if State === opts opts.generate(obj, anIO) else State.generate(obj, opts, anIO) end rescue JSON::NestingError raise ArgumentError, "exceed depth limit" end end
    .fast_generate(obj, opts)  ⇒ String  (mod_func)    Also known as: .fast_unparse
  
Arguments obj and opts here are the same as arguments obj and opts in .generate.
By default, generates JSON data without checking for circular references in obj (option max_nesting set to false, disabled).
Raises an exception if obj contains circular references:
a = []; b = []; a.push(b); b.push(a)
# Raises SystemStackError (stack level too deep):
JSON.fast_generate(a)# File 'ext/json/lib/json/common.rb', line 329
def fast_generate(obj, opts = nil) if State === opts state = opts else state = JSON.create_fast_state.configure(opts) end state.generate(obj) end
.fast_unparse (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 340
alias fast_unparse fast_generate
    .generate(obj, opts = nil)  ⇒ String  (mod_func)    Also known as: .unparse
  
Returns a String containing the generated JSON data.
See also .fast_generate, .pretty_generate.
Argument obj is the Ruby object to be converted to JSON.
Argument opts, if given, contains a Hash of options for the generation. See Generating Options.
When obj is an Array, returns a String containing a JSON array:
obj = ["foo", 1.0, true, false, nil]
json = JSON.generate(obj)
json # => '["foo",1.0,true,false,null]'When obj is a Hash, returns a String containing a JSON object:
obj = {foo: 0, bar: 's', baz: :bat}
json = JSON.generate(obj)
json # => '{"foo":0,"bar":"s","baz":"bat"}'For examples of generating from other Ruby objects, see Generating JSON from Other Objects.
Raises an exception if any formatting option is not a String.
Raises an exception if obj contains circular references:
a = []; b = []; a.push(b); b.push(a)
# Raises JSON::NestingError (nesting of 100 is too deep):
JSON.generate(a)# File 'ext/json/lib/json/common.rb', line 301
def generate(obj, opts = nil) if State === opts opts.generate(obj) else State.generate(obj, opts, nil) end end
.iconv(to, from, string)
Encodes string using String.encode.
# File 'ext/json/lib/json/common.rb', line 832
def self.iconv(to, from, string) string.encode(to, from) end
.load(source, proc = nil, options = {}) ⇒ Object (mod_func) Also known as: .restore
Returns the Ruby objects created by parsing the given source.
BEWARE: This method is meant to serialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it. If you must use it, use .unsafe_load instead to make it clear.
Since JSON version 2.8.0, load emits a deprecation warning when a non native type is deserialized, without create_additions being explicitly enabled, and in JSON version 3.0, load will have create_additions disabled by default.
- 
Argument sourcemust be, or be convertible to, a String:- 
If sourceresponds to instance methodto_str,source.to_strbecomes the source.
- 
If sourceresponds to instance methodto_io,source.to_io.readbecomes the source.
- 
If sourceresponds to instance methodread,source.readbecomes the source.
- 
If both of the following are true, source becomes the String 'null':- 
Option allow_blankspecifies a truthy value.
- 
The source, as defined above, is nilor the empty String''.
 
- 
- 
Otherwise, sourceremains the source.
 
- 
- 
Argument proc, if given, must be a Proc that accepts one argument. It will be called recursively with each result (depth-first order). See details below.
- 
Argument opts, if given, contains a Hash of options for the parsing. SeeParsing Options. The default options can be changed via method JSON.load_default_options=.
When no proc is given, modifies source as above and returns the result of parse(source, opts);  see #parse.
Source for following examples:
source = <<~JSON
  {
    "name": "Dave",
    "age" :40,
    "hats": [
      "Cattleman's",
      "Panama",
      "Tophat"
    ]
  }
JSONLoad a String:
ruby = JSON.load(source)
ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}Load an IO object:
require 'stringio'
object = JSON.load(StringIO.new(source))
object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}Load a File object:
path = 't.json'
File.write(path, source)
File.open(path) do |file|
  JSON.load(file)
end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}When proc is given:
- 
Modifies sourceas above.
- 
Gets the resultfrom callingparse(source, opts).
- 
Recursively calls proc(result).
- 
Returns the final result. 
Example:
require 'json'
# Some classes for the example.
class Base
  def initialize(attributes)
    @attributes = attributes
  end
end
class User    < Base; end
class Account < Base; end
class Admin   < Base; end
# The JSON source.
json = <<-EOF
{
  "users": [
      {"type": "User", "username": "jane", "email": "jane@example.com"},
      {"type": "User", "username": "john", "email": "john@example.com"}
  ],
  "accounts": [
      {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
      {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
  ],
  "admins": {"type": "Admin", "password": "0wn3d"}
}
EOF
# Deserializer method.
def deserialize_obj(obj, safe_types = %w(User Account Admin))
  type = obj.is_a?(Hash) && obj["type"]
  safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
end
# Call to JSON.load
ruby = JSON.load(json, proc {|obj|
  case obj
  when Hash
    obj.each {|k, v| obj[k] = deserialize_obj v }
  when Array
    obj.map! {|v| deserialize_obj v }
  end
})
pp rubyOutput:
{"users"=>
   [#<User:0x00000000064c4c98
     @attributes=
       {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
     #<User:0x00000000064c4bd0
     @attributes=
       {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
 "accounts"=>
   [{"account"=>
       #<Account:0x00000000064c4928
       @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
    {"account"=>
       #<Account:0x00000000064c4680
       @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
 "admins"=>
   #<Admin:0x00000000064c41f8
   @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}# File 'ext/json/lib/json/common.rb', line 714
def load(source, proc = nil, = nil) opts = if .nil? else .merge() end unless source.is_a?(String) if source.respond_to? :to_str source = source.to_str elsif source.respond_to? :to_io source = source.to_io.read elsif source.respond_to?(:read) source = source.read end end if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) recurse_proc(result, &proc) if proc result end
.load_file(path, opts = {}) ⇒ Object (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 250
def load_file(filespec, opts = nil) parse(File.read(filespec, encoding: Encoding::UTF_8), opts) end
.load_file!(path, opts = {}) (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 261
def load_file!(filespec, opts = {}) parse!(File.read(filespec, encoding: Encoding::UTF_8), opts) end
.merge_dump_options(opts, strict: NOT_SET) (mod_func)
[ GitHub ].parse(source, opts) ⇒ Object (mod_func)
Returns the Ruby objects created by parsing the given source.
Argument source contains the String to be parsed.
Argument opts, if given, contains a Hash of options for the parsing. See Parsing Options.
When source is a JSON array, returns a Ruby Array:
source = '["foo", 1.0, true, false, null]'
ruby = JSON.parse(source)
ruby # => ["foo", 1.0, true, false, nil]
ruby.class # => ArrayWhen source is a JSON object, returns a Ruby Hash:
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
ruby.class # => HashFor examples of parsing for all JSON data types, see Parsing JSON.
Parses nested JSON objects:
source = <<~JSON
  {
  "name": "Dave",
    "age" :40,
    "hats": [
      "Cattleman's",
      "Panama",
      "Tophat"
    ]
  }
JSON
ruby = JSON.parse(source)
ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}Raises an exception if source is not valid JSON:
# Raises JSON::ParserError (783: unexpected token at ''):
JSON.parse('')# File 'ext/json/lib/json/common.rb', line 220
def parse(source, opts = nil) Parser.parse(source, opts) end
.parse!(source, opts) ⇒ Object (mod_func)
# File 'ext/json/lib/json/common.rb', line 235
def parse!(source, opts = {}) opts = { :max_nesting => false, :allow_nan => true }.merge(opts) Parser.new(source, **(opts||{})).parse end
    .pretty_generate(obj, opts = nil)  ⇒ String  (mod_func)    Also known as: .pretty_unparse
  
Arguments obj and opts here are the same as arguments obj and opts in .generate.
Default options are:
{
  indent: '  ',   # Two spaces
  space: ' ',     # One space
  array_nl: "\n", # Newline
  object_nl: "\n" # Newline
}Example:
obj = {foo: [:, :baz], bat: {bam: 0, bad: 1}}
json = JSON.pretty_generate(obj)
puts jsonOutput:
{
  "foo": [
    "bar",
    "baz"
  ],
  "bat": {
    "bam": 0,
    "bad": 1
  }
}# File 'ext/json/lib/json/common.rb', line 374
def pretty_generate(obj, opts = nil) if State === opts state, opts = opts, nil else state = JSON.create_pretty_state end if opts if opts.respond_to? :to_hash opts = opts.to_hash elsif opts.respond_to? :to_h opts = opts.to_h else raise TypeError, "can't convert #{opts.class} into Hash" end state.configure(opts) end state.generate(obj) end
.pretty_unparse (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 395
alias pretty_unparse pretty_generate
.recurse_proc(result, &proc) (mod_func)
Recursively calls passed Proc if the parsed data structure is an Array or Hash
# File 'ext/json/lib/json/common.rb', line 740
def recurse_proc(result, &proc) # :nodoc: case result when Array result.each { |x| recurse_proc x, &proc } proc.call result when Hash result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc } proc.call result else proc.call result end end
.restore (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 753
alias restore load
.unparse (mod_func)
[ GitHub ]# File 'ext/json/lib/json/common.rb', line 312
alias unparse generate
.unsafe_load(source, proc = nil, options = {}) ⇒ Object (mod_func)
Returns the Ruby objects created by parsing the given source.
BEWARE: This method is meant to serialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it.
- 
Argument sourcemust be, or be convertible to, a String:- 
If sourceresponds to instance methodto_str,source.to_strbecomes the source.
- 
If sourceresponds to instance methodto_io,source.to_io.readbecomes the source.
- 
If sourceresponds to instance methodread,source.readbecomes the source.
- 
If both of the following are true, source becomes the String 'null':- 
Option allow_blankspecifies a truthy value.
- 
The source, as defined above, is nilor the empty String''.
 
- 
- 
Otherwise, sourceremains the source.
 
- 
- 
Argument proc, if given, must be a Proc that accepts one argument. It will be called recursively with each result (depth-first order). See details below.
- 
Argument opts, if given, contains a Hash of options for the parsing. SeeParsing Options. The default options can be changed via method JSON.unsafe_load_default_options=.
When no proc is given, modifies source as above and returns the result of parse(source, opts);  see #parse.
Source for following examples:
source = <<~JSON
  {
    "name": "Dave",
    "age" :40,
    "hats": [
      "Cattleman's",
      "Panama",
      "Tophat"
    ]
  }
JSONLoad a String:
ruby = JSON.unsafe_load(source)
ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}Load an IO object:
require 'stringio'
object = JSON.unsafe_load(StringIO.new(source))
object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}Load a File object:
path = 't.json'
File.write(path, source)
File.open(path) do |file|
  JSON.unsafe_load(file)
end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}When proc is given:
- 
Modifies sourceas above.
- 
Gets the resultfrom callingparse(source, opts).
- 
Recursively calls proc(result).
- 
Returns the final result. 
Example:
require 'json'
# Some classes for the example.
class Base
  def initialize(attributes)
    @attributes = attributes
  end
end
class User    < Base; end
class Account < Base; end
class Admin   < Base; end
# The JSON source.
json = <<-EOF
{
  "users": [
      {"type": "User", "username": "jane", "email": "jane@example.com"},
      {"type": "User", "username": "john", "email": "john@example.com"}
  ],
  "accounts": [
      {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
      {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
  ],
  "admins": {"type": "Admin", "password": "0wn3d"}
}
EOF
# Deserializer method.
def deserialize_obj(obj, safe_types = %w(User Account Admin))
  type = obj.is_a?(Hash) && obj["type"]
  safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
end
# Call to JSON.unsafe_load
ruby = JSON.unsafe_load(json, proc {|obj|
  case obj
  when Hash
    obj.each {|k, v| obj[k] = deserialize_obj v }
  when Array
    obj.map! {|v| deserialize_obj v }
  end
})
pp rubyOutput:
{"users"=>
   [#<User:0x00000000064c4c98
     @attributes=
       {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
     #<User:0x00000000064c4bd0
     @attributes=
       {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
 "accounts"=>
   [{"account"=>
       #<Account:0x00000000064c4928
       @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
    {"account"=>
       #<Account:0x00000000064c4680
       @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
 "admins"=>
   #<Admin:0x00000000064c41f8
   @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}# File 'ext/json/lib/json/common.rb', line 554
def unsafe_load(source, proc = nil, = nil) opts = if .nil? else .merge() end unless source.is_a?(String) if source.respond_to? :to_str source = source.to_str elsif source.respond_to? :to_io source = source.to_io.read elsif source.respond_to?(:read) source = source.read end end if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) recurse_proc(result, &proc) if proc result end