# module JSON

# 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

- `source` is a Ruby object.

- `opts` is a Hash object containing options that control both input allowed and output formatting.

The difference between the two methods is that `JSON.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 `JSON.parse` for less trusted sources.

#### Parsing JSON Arrays¶ ↑

When `source` is a JSON array, `JSON.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 # => Array

The 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, `JSON.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 # => Hash

The 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), `JSON.parse` returns a Ruby scalar.

String:

    ruby = JSON.parse('"foo"')
    ruby # => 'foo'
    ruby.class # => String

Integer:

    ruby = JSON.parse('1')
    ruby # => 1
    ruby.class # => Integer

Float:

    ruby = JSON.parse('1.0')
    ruby # => 1.0
    ruby.class # => Float
    ruby = JSON.parse('2.0e2')
    ruby # => 200
    ruby.class # => Float

Boolean:

    ruby = JSON.parse('true')
    ruby # => true
    ruby.class # => TrueClass
    ruby = JSON.parse('false')
    ruby # => false
    ruby.class # => FalseClass

Null:

    ruby = JSON.parse('null')
    ruby # => nil
    ruby.class # => NilClass

#### Parsing 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 # => Hash

Use 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 # => Array

Use 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 JSON Additions.

### Generating JSON¶ ↑

To generate a Ruby String containing JSON data, use method `JSON.generate(source, opts)`, where

- `source` is a Ruby object.

- `opts` is a Hash object containing options that control both input allowed and output formatting.

#### Generating JSON from Arrays¶ ↑

When the source is a Ruby Array, `JSON.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, `JSON.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, `JSON.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, `JSON.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`, `JSON.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, `JSON.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)

###### 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 `JSON.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 options `array_nl` or `object_nl` specify 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: [:bar, :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 # => String

You 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 display

This 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 JSON 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 # => BigDecimal

Complex:

    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 # Complex

Date:

    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 # Date

DateTime:

    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 # DateTime

Exception (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 # RuntimeError

OpenStruct:

    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 # OpenStruct

Range:

    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 # Range

Rational:

    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 # Rational

Regexp:

    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 # Regexp

Set:

    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 # Set

Struct:

    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 # Customer

Symbol:

    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 # Symbol

Time:

    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 # Time

### Custom 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 :bar, :baz
      def initialize(bar, baz)
        self.bar = bar
        self.baz = baz
      end
    end

Here'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'             => [ bar, baz ]
        }.to_json(*args)
      end
      # Deserialize JSON string by constructing new Foo object with arguments.
      def self.json_create(object)
        new(*object['a'])
      end
    end

Demonstration:

    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 display

Output:

    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)

### Constants

CREATE_ID_TLS_KEY
DEFAULT_CREATE_ID
Infinity
JSON_LOADED
MinusInfinity
NaN
VERSION

  `JSON` version

### Attributes

dump_default_options[RW]

Sets or returns the default options for the `JSON.dump` method. Initially:

    opts = JSON.dump_default_options
    opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false}

generator[R]

Returns the `JSON` generator module that is used by `JSON`. This is either `JSON::Ext::Generator` or JSON::Pure::Generator:

    JSON.generator # => JSON::Ext::Generator

load_default_options[RW]

Sets or returns default options for the `JSON.load` method. Initially:

    opts = JSON.load_default_options
    opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}

parser[R]

Returns the `JSON` parser class that is used by `JSON`. This is either `JSON::Ext::Parser` or JSON::Pure::Parser:

    JSON.parser # => JSON::Ext::Parser

state[RW]

Sets or Returns the `JSON` generator state class that is used by `JSON`. This is either `JSON::Ext::Generator::State` or JSON::Pure::Generator::State:

    JSON.state # => JSON::Ext::Generator::State

### Public Class Methods

JSON[object] → new_array or new_string click to toggle source

If `object` is a String, calls `JSON.parse` with `object` and `opts` (see method `parse`):

    json = '[0, 1, null]'
    JSON[json]# => [0, 1, nil]

Otherwise, calls `JSON.generate` with `object` and `opts` (see method `generate`):

    ruby = [0, 1, nil]
    JSON[ruby] # => '[0,1,null]'

    # File ext/json/lib/json/common.rb, line 18
    def [](object, opts = {})
      if object.respond_to? :to_str
        JSON.parse(object.to_str, opts)
      else
        JSON.generate(object, opts)
      end
    end

create_fast_state() click to toggle source

    # File ext/json/lib/json/common.rb, line 81
    def create_fast_state
      State.new(
        :indent         => '',
        :space          => '',
        :object_nl      => "",
        :array_nl       => "",
        :max_nesting    => false
      )
    end

create_id() click to toggle source

Returns the current create identifier. See also `JSON.create_id=`.

    # File ext/json/lib/json/common.rb, line 126
    def self.create_id
      Thread.current[CREATE_ID_TLS_KEY] || DEFAULT_CREATE_ID
    end

create_id=(new_value) click to toggle source

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 120
    def self.create_id=(new_value)
      Thread.current[CREATE_ID_TLS_KEY] = new_value.dup.freeze
    end

create_pretty_state() click to toggle source

    # File ext/json/lib/json/common.rb, line 91
    def create_pretty_state
      State.new(
        :indent         => '  ',
        :space          => ' ',
        :object_nl      => "\n",
        :array_nl       => "\n"
      )
    end

iconv(to, from, string) click to toggle source

Encodes string using `String.encode`.

    # File ext/json/lib/json/common.rb, line 653
    def self.iconv(to, from, string)
      string.encode(to, from)
    end

Alias for: load

### Public Instance Methods

dump(obj, io = nil, limit = nil) click to toggle source

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 `JSON.dump_default_options`.

- Argument `io`, if given, should respond to method `write`; the JSON String is written to `io`, and `io` is returned. If `io` is not given, the JSON String is returned.

- Argument `limit`, if given, is passed to `JSON.generate` as option `max_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 631
    def dump(obj, anIO = nil, limit = nil)
      if anIO and limit.nil?
        anIO = anIO.to_io if anIO.respond_to?(:to_io)
        unless anIO.respond_to?(:write)
          limit = anIO
          anIO = nil
        end
      end
      opts = JSON.dump_default_options
      opts = opts.merge(:max_nesting => limit) if limit
      result = generate(obj, opts)
      if anIO
        anIO.write result
        anIO
      else
        result
      end
    rescue JSON::NestingError
      raise ArgumentError, "exceed depth limit"
    end

fast_generate(obj, opts) → new_string click to toggle source

Arguments `obj` and `opts` here are the same as arguments `obj` and `opts` in `JSON.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 335
    def fast_generate(obj, opts = nil)
      if State === opts
        state, opts = opts, nil
      else
        state = JSON.create_fast_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

generate(obj, opts = nil) → new_string click to toggle source

Returns a String containing the generated JSON data.

See also `JSON.fast_generate`, `JSON.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 296
    def generate(obj, opts = nil)
      if State === opts
        state, opts = opts, nil
      else
        state = State.new
      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 = state.configure(opts)
      end
      state.generate(obj)
    end

load(source, proc = nil, options = {}) → object click to toggle source

Returns the Ruby objects created by parsing the given `source`.

- Argument `source` must be, or be convertible to, a String:

  - If `source` responds to instance method `to_str`, `source.to_str` becomes the source.

  - If `source` responds to instance method `to_io`, `source.to_io.read` becomes the source.

  - If `source` responds to instance method `read`, `source.read` becomes the source.

  - If both of the following are true, source becomes the String `'null'`:

    - Option `allow_blank` specifies a truthy value.

    - The source, as defined above, is `nil` or the empty String `''`.

  - Otherwise, `source` remains 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. 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 `opts`, if given, contains a Hash of options for the parsing. See Parsing 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 = <<-EOT
    {
    "name": "Dave",
      "age" :40,
      "hats": [
        "Cattleman's",
        "Panama",
        "Tophat"
      ]
    }
    EOT

Load 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 `source` as above.

- Gets the `result` from calling `parse(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 ruby

Output:

    {"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 557
    def load(source, proc = nil, options = {})
      opts = load_default_options.merge options
      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
      if opts[:allow_blank] && (source.nil? || source.empty?)
        source = 'null'
      end
      result = parse(source, opts)
      recurse_proc(result, &proc) if proc
      result
    end

Also aliased as: restore
load_file(path, opts={}) → object click to toggle source

Calls:

    parse(File.read(path), opts)

See method `parse`.

    # File ext/json/lib/json/common.rb, line 245
    def load_file(filespec, opts = {})
      parse(File.read(filespec), opts)
    end

load_file!(path, opts = {}) click to toggle source

Calls:

    JSON.parse!(File.read(path, opts))

See method `parse!`

    # File ext/json/lib/json/common.rb, line 256
    def load_file!(filespec, opts = {})
      parse!(File.read(filespec), opts)
    end

parse(source, opts) → object click to toggle source

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 # => Array

When `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 # => Hash

For examples of parsing for all JSON data types, see Parsing JSON.

Parses nested `JSON` objects:

    source = <<-EOT
    {
    "name": "Dave",
      "age" :40,
      "hats": [
        "Cattleman's",
        "Panama",
        "Tophat"
      ]
    }
    EOT
    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 215
    def parse(source, opts = {})
      Parser.new(source, **(opts||{})).parse
    end

parse!(source, opts) → object click to toggle source

Calls

    parse(source, opts)

with `source` and possibly modified `opts`.

Differences from `JSON.parse`:

- Option `max_nesting`, if not provided, defaults to `false`, which disables checking for nesting depth.

- Option `allow_nan`, if not provided, defaults to `true`.

    # File ext/json/lib/json/common.rb, line 230
    def parse!(source, opts = {})
      opts = {
        :max_nesting  => false,
        :allow_nan    => true
      }.merge(opts)
      Parser.new(source, **(opts||{})).parse
    end

pretty_generate(obj, opts = nil) → new_string click to toggle source

Arguments `obj` and `opts` here are the same as arguments `obj` and `opts` in `JSON.generate`.

Default options are:

    {
      indent: '  ',   # Two spaces
      space: ' ',     # One space
      array_nl: "\n", # Newline
      object_nl: "\n" # Newline
    }

Example:

    obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
    json = JSON.pretty_generate(obj)
    puts json

Output:

    {
      "foo": [
        "bar",
        "baz"
      ],
      "bat": {
        "bam": 0,
        "bad": 1
      }
    }

    # File ext/json/lib/json/common.rb, line 390
    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

### Private Instance Methods

Alias for: load