module JSON

def self.create_id

See also JSON.create_id=.
Returns the current create identifier.
def self.create_id
  Thread.current[:"JSON.create_id"] || 'json_class'
end

def self.create_id=(new_value)

JSON.create_id # => 'json_class'
hook of a class should be called; initial value is +json_class+:
Sets create identifier, which is used to decide if the _json_create_
def self.create_id=(new_value)
  Thread.current[:"JSON.create_id"] = new_value.dup.freeze
end

def [](object, opts = nil)

JSON[ruby] # => '[0,1,null]'
ruby = [0, 1, nil]
Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate):

JSON[json]# => [0, 1, nil]
json = '[0, 1, null]'
calls JSON.parse with +object+ and +opts+ (see method #parse):
If +object+ is a \String,

JSON[object] -> new_array or new_string
:call-seq:
def [](object, opts = nil)
  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

def const_missing(const_name)

def const_missing(const_name)
  case const_name
  when :PRETTY_STATE_PROTOTYPE
    if RUBY_VERSION >= "3.0"
      warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated
    else
      warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
    end
    state.new(PRETTY_GENERATE_OPTIONS)
  else
    super
  end
end

def deep_const_get(path) # :nodoc:

:nodoc:
the given path, an ArgumentError is raised.
level (absolute namespace path?). If there doesn't exist a constant at
either ::A::B::C or A::B::C. In any case, A has to be located at the top
Return the constant located at _path_. The format of _path_ has to be
def deep_const_get(path) # :nodoc:
  Object.const_get(path)
rescue NameError => e
  raise ArgumentError, "can't get const #{path}: #{e}"
end

def deprecated_singleton_attr_accessor(*attrs)

def deprecated_singleton_attr_accessor(*attrs)
  args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
  attrs.each do |attr|
    singleton_class.class_eval <<~RUBY
      def #{attr}
        warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
        @#{attr}
      end
      def #{attr}=(val)
        warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
        @#{attr} = val
      end
      def _#{attr}
        @#{attr}
      end
    RUBY
  end
end

def dump(obj, anIO = nil, limit = nil, kwargs = nil)

{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
Output:
puts File.read(path)
end # => #
JSON.dump(obj, file)
File.open(path, 'w') do |file|
path = 't.json'
When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+:

json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}"
json = JSON.dump(obj)
obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
When argument +io+ is not given, returns the \JSON \String generated from +obj+:

---

- Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+.
If +io+ is not given, the \JSON \String is returned.
the \JSON \String is written to +io+, and +io+ is returned.
- Argument +io+, if given, should respond to method +write+;

The default options can be changed via method JSON.dump_default_options.

Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result.

JSON.dump(obj, io = nil, limit = nil)
:call-seq:
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 = opts.merge(kwargs) if kwargs
  begin
    State.generate(obj, opts, anIO)
  rescue JSON::NestingError
    raise ArgumentError, "exceed depth limit"
  end
end

def fast_generate(obj, opts = nil)

JSON.fast_generate(a)
# Raises SystemStackError (stack level too deep):
a = []; b = []; a.push(b); b.push(a)
Raises an exception if +obj+ contains circular references:

for circular references in +obj+ (option +max_nesting+ set to +false+, disabled).
By default, generates \JSON data without checking

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

JSON.fast_generate(obj, opts) -> new_string
:call-seq:
def fast_generate(obj, opts = nil)
  if RUBY_VERSION >= "3.0"
    warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
  else
    warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
  end
  generate(obj, opts)
end

def fast_unparse(...)

def fast_unparse(...)
  if RUBY_VERSION >= "3.0"
    warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
  else
    warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
  end
  generate(...)
end

def generate(obj, opts = nil)


JSON.generate(a)
# Raises JSON::NestingError (nesting of 100 is too deep):
a = []; b = []; a.push(b); b.push(a)
Raises an exception if +obj+ contains circular references:

Raises an exception if any formatting option is not a \String.

---

{Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects].
For examples of generating from other Ruby objects, see

json # => '{"foo":0,"bar":"s","baz":"bat"}'
json = JSON.generate(obj)
obj = {foo: 0, bar: 's', baz: :bat}
When +obj+ is a \Hash, returns a \String containing a \JSON object:

json # => '["foo",1.0,true,false,null]'
json = JSON.generate(obj)
obj = ["foo", 1.0, true, false, nil]
When +obj+ is an \Array, returns a \String containing a \JSON array:

---

See {Generating Options}[#module-JSON-label-Generating+Options].
Argument +opts+, if given, contains a \Hash of options for the generation.

Argument +obj+ is the Ruby object to be converted to \JSON.

See also JSON.fast_generate, JSON.pretty_generate.

Returns a \String containing the generated \JSON data.

JSON.generate(obj, opts = nil) -> new_string
:call-seq:
def generate(obj, opts = nil)
  if State === opts
    opts.generate(obj)
  else
    State.generate(obj, opts, nil)
  end
end

def generator=(generator) # :nodoc:

:nodoc:
Set the module _generator_ to be used by JSON.
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
ensure
  $VERBOSE = old
end

def load(source, proc = nil, options = nil)


@attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
#"admins"=>
@attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
#{"account"=>
@attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
#[{"account"=>
"accounts"=>
{"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
@attributes=
#{"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
@attributes=
[#{"users"=>
Output:
pp ruby
})
end
obj.map! {|v| deserialize_obj v }
when Array
obj.each {|k, v| obj[k] = deserialize_obj v }
when Hash
case obj
ruby = JSON.load(json, proc {|obj|
# Call to JSON.load
end
safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
type = obj.is_a?(Hash) && obj["type"]
def deserialize_obj(obj, safe_types = %w(User Account Admin))
# Deserializer method.
EOF
}
"admins": {"type": "Admin", "password": "0wn3d"}
],
{"account": {"type": "Account", "paid": false, "account_id": "1235"}}
{"account": {"type": "Account", "paid": true, "account_id": "1234"}},
"accounts": [
],
{"type": "User", "username": "john", "email": "john@example.com"}
{"type": "User", "username": "jane", "email": "jane@example.com"},
"users": [
{
json = <<-EOF
# The JSON source.
class Admin < Base; end
class Account < Base; end
class User < Base; end
end
end
@attributes = attributes
def initialize(attributes)
class Base
# Some classes for the example.

require 'json'
Example:

- Returns the final result.
- Recursively calls proc(result).
- Gets the +result+ from calling parse(source, opts).
- Modifies +source+ as above.
When +proc+ is given:

---

end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
JSON.load(file)
File.open(path) do |file|
File.write(path, source)
path = 't.json'
Load a \File object:

object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
object = JSON.load(StringIO.new(source))
require 'stringio'
Load an \IO object:

ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
ruby = JSON.load(source)
Load a \String:

JSON
}
]
"Tophat"
"Panama",
"Cattleman's",
"hats": [
"age" :40,
"name": "Dave",
{
source = <<~JSON
Source for following examples:

parse(source, opts); see #parse.
When no +proc+ is given, modifies +source+ as above and returns the result of

---

The default options can be changed via method JSON.load_default_options=.
See {Parsing Options}[#module-JSON-label-Parsing+Options].
- Argument +opts+, if given, contains a \Hash of options for the parsing.
See details below.
It will be called recursively with each result (depth-first order).
- Argument +proc+, if given, must be a \Proc that accepts one argument.
- Otherwise, +source+ remains the source.
- The source, as defined above, is +nil+ or the empty \String ''.
- Option +allow_blank+ specifies a truthy value.
- If both of the following are true, source becomes the \String 'null':
source.read becomes the source.
- If +source+ responds to instance method +read+,
source.to_io.read becomes the source.
- If +source+ responds to instance method +to_io+,
source.to_str becomes the source.
- If +source+ responds to instance method +to_str+,
- Argument +source+ must be, or be convertible to, a \String:

by default.
enabled, and in JSON version 3.0, `load` will have `create_additions` disabled
non native type is deserialized, without `create_additions` being explicitly
Since JSON version 2.8.0, `load` emits a deprecation warning when a

If you must use it, use JSON.unsafe_load instead to make it clear.
be dangerous to allow untrusted users to pass JSON sources into it.
like from your own database server or clients under your control, it could
BEWARE: This method is meant to serialise data from trusted user input,

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

JSON.load(source, proc = nil, options = {}) -> object
:call-seq:
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
  if proc
    opts = opts.dup
    opts[:on_load] = proc.to_proc
  end
  parse(source, opts)
end

def load_file(filespec, opts = nil)

See method #parse.

parse(File.read(path), opts)
Calls:

JSON.load_file(path, opts={}) -> object
:call-seq:
def load_file(filespec, opts = nil)
  parse(File.read(filespec, encoding: Encoding::UTF_8), opts)
end

def load_file!(filespec, opts = nil)

See method #parse!

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

JSON.load_file!(path, opts = {})
:call-seq:
def load_file!(filespec, opts = nil)
  parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
end

def parse(source, opts = nil)


JSON.parse('')
# Raises JSON::ParserError (783: unexpected token at ''):
Raises an exception if +source+ is not valid JSON:

---

ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
ruby = JSON.parse(source)
JSON
}
]
"Tophat"
"Panama",
"Cattleman's",
"hats": [
"age" :40,
"name": "Dave",
{
source = <<~JSON
Parses nested JSON objects:

{Parsing \JSON}[#module-JSON-label-Parsing+JSON].
For examples of parsing for all \JSON data types, see

ruby.class # => Hash
ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
ruby = JSON.parse(source)
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
When +source+ is a \JSON object, returns a Ruby \Hash:

ruby.class # => Array
ruby # => ["foo", 1.0, true, false, nil]
ruby = JSON.parse(source)
source = '["foo", 1.0, true, false, null]'
When +source+ is a \JSON array, returns a Ruby \Array:

---

See {Parsing Options}[#module-JSON-label-Parsing+Options].
Argument +opts+, if given, contains a \Hash of options for the parsing.

Argument +source+ contains the \String to be parsed.

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

JSON.parse(source, opts) -> object
:call-seq:
def parse(source, opts = nil)
  opts = ParserOptions.prepare(opts) unless opts.nil?
  Parser.parse(source, opts)
end

def parse!(source, opts = nil)

- Option +allow_nan+, if not provided, defaults to +true+.
which disables checking for nesting depth.
- Option +max_nesting+, if not provided, defaults to +false+,
Differences from JSON.parse:

with +source+ and possibly modified +opts+.
parse(source, opts)
Calls

JSON.parse!(source, opts) -> object
:call-seq:
def parse!(source, opts = nil)
  if opts.nil?
    parse(source, PARSE_L_OPTIONS)
  else
    parse(source, PARSE_L_OPTIONS.merge(opts))
  end
end

def parser=(parser) # :nodoc:

:nodoc:
Set the JSON parser class _parser_ to be used by JSON.
def parser=(parser) # :nodoc:
  @parser = parser
  remove_const :Parser if const_defined?(:Parser, false)
  const_set :Parser, parser
end

def pretty_generate(obj, opts = nil)


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

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

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

JSON.pretty_generate(obj, opts = nil) -> new_string
:call-seq:
def pretty_generate(obj, opts = nil)
  return state.generate(obj) if State === opts
  options = PRETTY_GENERATE_OPTIONS
  if opts
    unless opts.is_a?(Hash)
      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
    end
    options = options.merge(opts)
  end
  State.generate(obj, options, nil)
end

def pretty_unparse(...)

def pretty_unparse(...)
  if RUBY_VERSION >= "3.0"
    warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated
  else
    warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
  end
  pretty_generate(...)
end

def restore(...)

def restore(...)
  if RUBY_VERSION >= "3.0"
    warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated
  else
    warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1
  end
  load(...)
end

def unparse(...)

so usage still exist in the wild.
All these were meant to be deprecated circa 2009, but were just set as undocumented
:stopdoc:
def unparse(...)
  if RUBY_VERSION >= "3.0"
    warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
  else
    warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
  end
  generate(...)
end

def unsafe_load(source, proc = nil, options = nil)


@attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
#"admins"=>
@attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
#{"account"=>
@attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
#[{"account"=>
"accounts"=>
{"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
@attributes=
#{"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
@attributes=
[#{"users"=>
Output:
pp ruby
})
end
obj.map! {|v| deserialize_obj v }
when Array
obj.each {|k, v| obj[k] = deserialize_obj v }
when Hash
case obj
ruby = JSON.unsafe_load(json, proc {|obj|
# Call to JSON.unsafe_load
end
safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
type = obj.is_a?(Hash) && obj["type"]
def deserialize_obj(obj, safe_types = %w(User Account Admin))
# Deserializer method.
EOF
}
"admins": {"type": "Admin", "password": "0wn3d"}
],
{"account": {"type": "Account", "paid": false, "account_id": "1235"}}
{"account": {"type": "Account", "paid": true, "account_id": "1234"}},
"accounts": [
],
{"type": "User", "username": "john", "email": "john@example.com"}
{"type": "User", "username": "jane", "email": "jane@example.com"},
"users": [
{
json = <<-EOF
# The JSON source.
class Admin < Base; end
class Account < Base; end
class User < Base; end
end
end
@attributes = attributes
def initialize(attributes)
class Base
# Some classes for the example.

require 'json'
Example:

- Returns the final result.
- Recursively calls proc(result).
- Gets the +result+ from calling parse(source, opts).
- Modifies +source+ as above.
When +proc+ is given:

---

end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
JSON.unsafe_load(file)
File.open(path) do |file|
File.write(path, source)
path = 't.json'
Load a \File object:

object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
object = JSON.unsafe_load(StringIO.new(source))
require 'stringio'
Load an \IO object:

ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
ruby = JSON.unsafe_load(source)
Load a \String:

JSON
}
]
"Tophat"
"Panama",
"Cattleman's",
"hats": [
"age" :40,
"name": "Dave",
{
source = <<~JSON
Source for following examples:

parse(source, opts); see #parse.
When no +proc+ is given, modifies +source+ as above and returns the result of

---

The default options can be changed via method JSON.unsafe_load_default_options=.
See {Parsing Options}[#module-JSON-label-Parsing+Options].
- Argument +opts+, if given, contains a \Hash of options for the parsing.
See details below.
It will be called recursively with each result (depth-first order).
- Argument +proc+, if given, must be a \Proc that accepts one argument.
- Otherwise, +source+ remains the source.
- The source, as defined above, is +nil+ or the empty \String ''.
- Option +allow_blank+ specifies a truthy value.
- If both of the following are true, source becomes the \String 'null':
source.read becomes the source.
- If +source+ responds to instance method +read+,
source.to_io.read becomes the source.
- If +source+ responds to instance method +to_io+,
source.to_str becomes the source.
- If +source+ responds to instance method +to_str+,
- Argument +source+ must be, or be convertible to, a \String:

be dangerous to allow untrusted users to pass JSON sources into it.
like from your own database server or clients under your control, it could
BEWARE: This method is meant to serialise data from trusted user input,

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

JSON.unsafe_load(source, proc = nil, options = {}) -> object
:call-seq:
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