module JSON - json: Ruby Standard Library Documentation

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

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

Infinity
JSON_LOADED
MinusInfinity
NOT_SET
NaN
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}

generator[R]

Returns the `JSON` generator module that is used by `JSON`.

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

state[RW]

Sets or Returns the `JSON` generator state class that is used by `JSON`.

unsafe_load_default_options[RW]

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

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

### 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 json/lib/json/common.rb, line 23
    def [](object, opts = {})
      if object.is_a?(String)
        return JSON.parse(object, opts)
      elsif object.respond_to?(:to_str)
        str = object.to_str
        if str.is_a?(String)
          return JSON.parse(str, opts)
        end
      end

      JSON.generate(object, opts)
    end

create_fast_state() click to toggle source

    # File json/lib/json/common.rb, line 80
    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 json/lib/json/common.rb, line 115
    def self.create_id
      Thread.current[:"JSON.create_id"] || 'json_class'
    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 json/lib/json/common.rb, line 109
    def self.create_id=(new_value)
      Thread.current[:"JSON.create_id"] = new_value.dup.freeze
    end

create_pretty_state() click to toggle source

    # File json/lib/json/common.rb, line 90
    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 json/lib/json/common.rb, line 832
    def self.iconv(to, from, string)
      string.encode(to, from)
    end

restore(source, proc = nil, options = nil)
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 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.dump_default_options
      opts = opts.merge(:max_nesting => limit) if limit
      opts = merge_dump_options(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) → 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 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

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

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

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

- 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 = <<~JSON
      {
        "name": "Dave",
        "age" :40,
        "hats": [
          "Cattleman's",
          "Panama",
          "Tophat"
        ]
      }
    JSON

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 json/lib/json/common.rb, line 714
    def load(source, proc = nil, options = nil)
      opts = if options.nil?
        load_default_options
      else
        load_default_options.merge(options)
      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

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

Calls:

    parse(File.read(path), opts)

See method `parse`.

    # File 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 = {}) click to toggle source

Calls:

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

See method `parse!`

    # File 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) click to toggle source

    # File json/lib/json/common.rb, line 836
    def merge_dump_options(opts, strict: NOT_SET)
      opts = opts.merge(strict: strict) if NOT_SET != strict
      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 = <<~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 json/lib/json/common.rb, line 220
    def parse(source, opts = nil)
      Parser.parse(source, opts)
    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 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) → 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 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

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

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

- Argument `opts`, if given, contains a Hash of options for the parsing. See Parsing 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"
        ]
      }
    JSON

Load 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 `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.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 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 json/lib/json/common.rb, line 554
    def unsafe_load(source, proc = nil, options = nil)
      opts = if options.nil?
        unsafe_load_default_options
      else
        unsafe_load_default_options.merge(options)
      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

### Private Instance Methods

restore(source, proc = nil, options = nil)
Alias for: load