module JSON
JavaScript Object Notation (JSON)
JSON is a lightweight data-interchange format.
JSON is easy for us humans to read and write, and equally simple for machines to read (parse) and write (generate).
JSON is language-independent, making it an ideal interchange format for applications in differing programming languages and on differing operating systems.
JSON Values
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:
where
-
sourceis aRubyobject. -
optsis 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; You can set it to false to disable depth checking entirely, but that is dangerous when parsing untrusted input.
With the default, 100:
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_duplicate_key specifies whether duplicate keys in objects should be ignored or cause an error to be raised:
When set to false, the default:
JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
When set to true:
# The last value is used.
JSON.parse('{"a": 1, "a":2}', allow_duplicate_key: true) => {"a" => 2}
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]
Option allow_trailing_comma (boolean) specifies whether to allow trailing commas in objects and arrays; defaults to false.
With the default, false:
JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError)
When enabled:
JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
Option allow_comments (boolean) specifies whether to allow JavaScript style comments (either // comment or /* comment */); defaults to false.
When set to false, the default:
JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
When set to true, comments are ignored:
JSON.parse('/* comment */ {"a": 1, "a":2} // more comment') # => {"a" => 2}
Option allow_control_characters (boolean) specifies whether to allow unescaped ASCII control characters, such as newlines, in strings; defaults to false.
With the default, false:
JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
When enabled:
JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
Option allow_invalid_escape (boolean) specifies whether to ignore backslahes that are followed by an invalid escape character in strings; defaults to false.
With the default, false:
JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
When enabled:
JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
Output Options
Option freeze (boolean) specifies whether the returned objects will be frozen; defaults to false.
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}>
Generating JSON
To generate a Ruby String containing JSON data, use method JSON.generate(source, opts), where
-
sourceis aRubyobject. -
optsis a Hash object containing options that control both input allowed and output formatting.
Generating JSON from Arrays
When the source is a Ruby Array, 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, JSON::NaN, JSON::Infinity, JSON::MinusInfinity] JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
Option allow_duplicate_key (boolean) specifies whether hashes with duplicate keys should be allowed or produce an error. defaults to emit a deprecation warning.
With the default, false:
JSON.generate({ foo: 1, "foo" => 2 }) # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
With true
JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: true) # => '{"foo":1,"foo":2}'
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)
With false:
obj = [] obj[0] = obj # Raises SystemStackError: stack level too deep JSON.generate(obj, max_nesting: false)
Setting max_nesting to false or a very large number can lead to a stack overflow which may leave the process in an unrecoverable state. It is highly discouraged.
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,''; has no effect unless optionsarray_nlorobject_nlspecify newlines. -
Option
space(String) specifies a string (usually a space) to be inserted after the colon in each JSON objectβs pair; defaults to the empty String,''. -
Option
space_before(String) specifies a string (usually a space) to be inserted before the colon in each JSON objectβs pair; defaults to the empty String,''. -
Option
sort_keys(boolean or Proc) controls whether and how the keys of a hash are sorted when generating the output; defaults tofalse. Whentrue, keys are sorted lexicographically. When a Proc, it receives the entire Hash and must return a Hash with its pairs in the desired order, allowing for arbitrary sort orders.
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
}
}
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
JSONvalues: {β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_duplicate_key specifies whether duplicate keys in objects should be ignored or cause an error to be raised:
When not specified: # The last value is used and a deprecation warning emitted. JSON.parse(β{βaβ: 1, βaβ:2}β) => {βaβ => 2} # warning: detected duplicate keys in JSON object. # This will raise an error in json 3.0 unless enabled via allow_duplicate_key: true
When set to true # The last value is used. JSON.parse(β{βaβ: 1, βaβ:2}β) => {βaβ => 2}
When set to false, the future default: JSON.parse(β{βaβ: 1, βaβ:2}β) => duplicate key at line 1 column 1 (JSON::ParserError)
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]
Option allow_trailing_comma (boolean) specifies whether to allow trailing commas in objects and arrays; defaults to false.
With the default, false: JSON.parse(β[1,]β) # unexpected character: β]β at line 1 column 4 (JSON::ParserError)
When enabled: JSON.parse(β[1,]β, allow_trailing_comma: true) # => [1]
Output Options
Option freeze (boolean) specifies whether the returned objects will be frozen; defaults to false.
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 allow_duplicate_key (boolean) specifies whether hashes with duplicate keys should be allowed or produce an error. defaults to emit a deprecation warning.
With the default, (not set): Warning = true JSON.generate({ foo: 1, βfooβ => 2 }) # warning: detected duplicate key βfooβ in {foo: 1, βfooβ => 2}. # This will raise an error in json 3.0 unless enabled via allow_duplicate_key: true # => β{βfooβ:1,βfooβ:2}β
With false JSON.generate({ foo: 1, βfooβ => 2 }, allow_duplicate_key: false) # detected duplicate key βfooβ in {foo: 1, βfooβ => 2} (JSON::GeneratorError)
In version 3.0, false will become the default.
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 eachJSONarray; defaults to the emptyString,''. -
Option
object_nl(String) specifies a string (usually a newline) to be inserted after eachJSONobject; defaults to the emptyString,''. -
Option
indent(String) specifies the string (usually spaces) to be used for indentation; defaults to the emptyString,''; defaults to the emptyString,''; has no effect unless optionsarray_nlorobject_nlspecify newlines. -
Option
space(String) specifies a string (usually a space) to be inserted after the colon in eachJSONobjectβs pair; defaults to the emptyString,''. -
Option
space_before(String) specifies a string (usually a space) to be inserted before the colon in eachJSONobjectβs pair; defaults to the emptyString,''.
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
Note that JSON Additions must only be used with trusted data, and is deprecated.
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) 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
- Fragment
-
FragmentofJSONdocument that is to be included as is:fragment = JSON::Fragment.new("[1, 2, 3]") JSON.generate({ count: 3, items: fragments })
This allows to easily assemble multiple
JSONfragments that have been persisted somewhere without having to parse them nor resorting to string interpolation.Note: no validation is performed on the provided string. It is the responsibility of the caller to ensure the string contains valid
JSON. - Infinity
- MinusInfinity
- NaN
- VERSION
Attributes
Public Class Methods
(untyped object, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 54 def [](object, opts = nil) opts ||= {}.freeze 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
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]'
If object is a String, calls JSON.parse with object and opts (see method
parse): json = β[0, 1, null]β JSON# => [0, 1, nil]
Otherwise, calls JSON.generate with object and opts (see method
() → _ToS
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 755
def self.create_id: () -> _ToS
Returns the current create identifier. See also JSON.create_id=.
(_ToS create_id) → _ToS
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 765
def self.create_id=: (_ToS create_id) -> _ToS
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β
(_ToJson obj, ?Integer limit) → String
(_ToJson obj, _WritableIO anIO) → _Write
(_ToJson obj, _Write anIO, ?Integer limit) → _Write
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 799
def self?.dump: (_ToJson obj, ?Integer limit) -> String
| (_ToJson obj, _WritableIO anIO) -> _Write
| (_ToJson obj, _Write anIO, ?Integer limit) -> _Write
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 methodwrite; theJSONStringis written toio, andiois returned. Ifiois not given, theJSONStringis returned. -
Argument
limit, if given, is passed toJSON.generateas optionmax_nesting.
When argument io is not given, returns the JSON String generated from obj: obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} json = JSON.dump(obj) json # => β{\βfoo\β:[0,1],\βbar\β:{\βbaz\β:2,\βbat\β:3},\βbam\β:\βbad\β}β
When argument io is given, writes the JSON String to io and returns io: path = βt.jsonβ File.open(path, βwβ) do |file| JSON.dump(obj, file) end # => #<File:t.json (closed)> puts File.read(path)
Output: {βfooβ:[0,1],βbarβ:{βbazβ:2,βbatβ:3},βbamβ:βbadβ}
() → options
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 809
def self.dump_default_options: () -> options
Sets or returns the default options for the JSON.dump method. Initially: opts = JSON.dump_default_options opts # => {:max_nesting=>false, :allow_nan=>true}
(options) → options
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 817
def self.dump_default_options=: (options) -> options
Sets or returns the default options for the JSON.dump method. Initially: opts = JSON.dump_default_options opts # => {:max_nesting=>false, :allow_nan=>true}
(_ToJson obj, ?options opts) → String
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 835
def self?.fast_generate: (_ToJson obj, ?options opts) -> String
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 vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 874
def self?.generate: (_ToJson obj, ?options opts) -> String
Returns a String containing the generated JSON data.
See also 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)
(generator generator) → void
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 881
def self.generator=: (generator generator) -> void
(string | _ReadableIO | _Read source, ?options options) → untyped
[T] (string | _ReadableIO | _Read source, ^(?) → T, ?options options) → T
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1023
def self?.load: (string | _ReadableIO | _Read source, ?options options) -> untyped
| [T] (string | _ReadableIO | _Read source, ^(?) -> T, ?options options) -> T
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
sourcemust be, or be convertible to, a String:-
If
sourceresponds to instance methodto_str,source.to_strbecomes the source. -
If
sourceresponds to instance methodto_io,source.to_io.readbecomes the source. -
If
sourceresponds to instance methodread,source.readbecomes the source. -
If both of the following are true, source becomes the
String'null':-
Option
allow_blankspecifies a truthy value. -
The source, as defined above, is
nilor the emptyString''.
-
-
Otherwise,
sourceremains the source.
-
-
Argument
proc, if given, must be aProcthat accepts one argument. It will be called recursively with each result (depth-first order). See details below. -
Argument
opts, if given, contains aHashof options for the parsing. See Parsing Options. The default options can be changed via methodJSON.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 obj }) 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β}>}
() → options
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1054
def self.load_default_options: () -> options
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}
(options) → options
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1062
def self.load_default_options=: (options) -> options
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}
(string path, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1035
def self?.load_file: (string path, ?options opts) -> untyped
Calls: parse(File.read(path), opts)
See method parse.
(string path, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1046
def self?.load_file!: (string path, ?options opts) -> untyped
Calls: JSON.parse!(File.read(path, opts))
See method parse!
(string source, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1113
def self?.parse: (string source, ?options opts) -> untyped
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(β)
(string source, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1129
def self?.parse!: (string source, ?options opts) -> untyped
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.
(parser parser) → void
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1136
def self.parser=: (parser parser) -> void
(_ToJson obj, ?options opts) → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs, line 1170
def self?.pretty_generate: (_ToJson obj, ?options opts) -> untyped
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 } }
Public Instance Methods
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 754 def dump(obj, anIO = nil, kwargs = nil) if kwargs.nil? if anIO.is_a?(Hash) kwargs = anIO anIO = nil end end if anIO&.respond_to?(:to_io) anIO = anIO.to_io end opts = { allow_nan: true, } opts.merge!(kwargs) if kwargs State.generate(obj, opts, anIO) end
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 methodwrite; the JSON String is written toio, andiois returned. Ifiois not given, the JSON String is returned.
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 vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 378 def generate(obj, opts = nil) if State === opts opts.generate(obj) else State.generate(obj, opts.frozen? ? opts : opts.dup, nil) end end
Returns a String containing the generated JSON data.
See also 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 vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 706 def load(source, proc = nil, allow_blank: true, **options) 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 allow_blank && (source.nil? || (String === source && source.empty?)) source = 'null' end if proc parse(source, allow_nan: true, on_load: proc.to_proc, **options) else parse(source, allow_nan: true, **options) end end
Returns the Ruby objects created by parsing the given source.
-
Argument
sourcemust be, or be convertible to, a String:-
If
sourceresponds to instance methodto_str,source.to_strbecomes the source. -
If
sourceresponds to instance methodto_io,source.to_io.readbecomes the source. -
If
sourceresponds to instance methodread,source.readbecomes the source. -
If both of the following are true, source becomes the String
'null':-
Option
allow_blankspecifies a truthy value. -
The source, as defined above, is
nilor the empty String''.
-
-
Otherwise,
sourceremains the source.
-
-
Argument
proc, if given, must be a Proc that accepts one argument. It will be called recursively with each result (depth-first order). See details below. -
Argument
opts, if given, contains a Hash of options for the parsing. See Parsing 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
sourceas above. -
Gets the
resultfrom callingparse(source, opts). -
Recursively calls
proc(result). -
Returns the final result.
Example:
require 'json' # Some classes for the example. class Base def initialize(attributes) @attributes = attributes end end class User < Base; end class Account < Base; end class Admin < Base; end # The JSON source. json = <<-EOF { "users": [ {"type": "User", "username": "jane", "email": "jane@example.com"}, {"type": "User", "username": "john", "email": "john@example.com"} ], "accounts": [ {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, {"account": {"type": "Account", "paid": false, "account_id": "1235"}} ], "admins": {"type": "Admin", "password": "0wn3d"} } EOF # Deserializer method. def deserialize_obj(obj, safe_types = %w(User Account Admin)) type = obj.is_a?(Hash) && obj["type"] safe_types.include?(type) ? Object.const_get(type).new(obj) : obj end # Call to JSON.load ruby = JSON.load(json, proc {|obj| case obj when Hash obj.each {|k, v| obj[k] = deserialize_obj v } when Array obj.map! {|v| deserialize_obj v } end obj }) 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"}>}
Source
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 327 def load_file(filespec, ...) parse(File.read(filespec, encoding: Encoding::UTF_8), ...) end
Source
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 338 def load_file!(filespec, ...) parse!(File.read(filespec, encoding: Encoding::UTF_8), ...) end
Source
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 296 def parse(source, on_load: nil, object_class: nil, array_class: nil, **options) if object_class || array_class on_load = ParserOptions.on_load(on_load, object_class, array_class) end options[:on_load] = on_load if on_load Parser.parse(source, options) end
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 unexpected character: 'invalid' at line 1 column 1 : JSON.parse('invalid')
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 316 def parse!(source, **options) parse(source, max_nesting: false, allow_nan: true, **options) end
Calls
parse(source, opts)
with source and possibly modified opts.
Differences from JSON.parse:
-
Option
max_nesting, if not provided, defaults tofalse, which disables checking for nesting depth. -
Option
allow_nan, if not provided, defaults totrue.
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 424 def pretty_generate(obj, opts = nil) return opts.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
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
}
}
Source
# File vendor/bundle/ruby/4.0.0/gems/json-3.0.0/lib/json/common.rb, line 576 def unsafe_load(source, proc = nil, **options) load(source, proc, max_nesting: false, **options) end
Returns the Ruby objects created by parsing the given source.
BEWARE: This method is meant to deserialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it.
-
Argument
sourcemust be, or be convertible to, a String:-
If
sourceresponds to instance methodto_str,source.to_strbecomes the source. -
If
sourceresponds to instance methodto_io,source.to_io.readbecomes the source. -
If
sourceresponds to instance methodread,source.readbecomes the source. -
If both of the following are true, source becomes the String
'null':-
Option
allow_blankspecifies a truthy value. -
The source, as defined above, is
nilor the empty String''.
-
-
Otherwise,
sourceremains the source.
-
-
Argument
proc, if given, must be a Proc that accepts one argument. It will be called recursively with each result (depth-first order). See details below. -
Argument
opts, if given, contains a Hash of options for the parsing. See Parsing 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
sourceas above. -
Gets the
resultfrom callingparse(source, opts). -
Recursively calls
proc(result). -
Returns the final result.
Example:
require 'json' # Some classes for the example. class Base def initialize(attributes) @attributes = attributes end end class User < Base; end class Account < Base; end class Admin < Base; end # The JSON source. json = <<-EOF { "users": [ {"type": "User", "username": "jane", "email": "jane@example.com"}, {"type": "User", "username": "john", "email": "john@example.com"} ], "accounts": [ {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, {"account": {"type": "Account", "paid": false, "account_id": "1235"}} ], "admins": {"type": "Admin", "password": "0wn3d"} } EOF # Deserializer method. def deserialize_obj(obj, safe_types = %w(User Account Admin)) type = obj.is_a?(Hash) && obj["type"] safe_types.include?(type) ? Object.const_get(type).new(obj) : obj end # Call to JSON.unsafe_load ruby = JSON.unsafe_load(json, proc {|obj| case obj when Hash obj.each {|k, v| obj[k] = deserialize_obj v } when Array obj.map! {|v| deserialize_obj v } end obj }) 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"}>}