json 1.0.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +503 -0
  3. data/LICENSE +56 -0
  4. data/README.md +416 -0
  5. data/ext/json/ext/fbuffer/fbuffer.h +187 -0
  6. data/ext/json/ext/generator/depend +1 -0
  7. data/ext/json/ext/generator/extconf.rb +2 -7
  8. data/ext/json/ext/generator/generator.c +1312 -338
  9. data/ext/json/ext/generator/generator.h +177 -0
  10. data/ext/json/ext/parser/depend +1 -0
  11. data/ext/json/ext/parser/extconf.rb +28 -5
  12. data/ext/json/ext/parser/parser.c +1349 -689
  13. data/ext/json/ext/parser/parser.h +96 -0
  14. data/ext/json/ext/parser/parser.rl +644 -188
  15. data/ext/json/extconf.rb +3 -0
  16. data/json.gemspec +68 -0
  17. data/lib/json/add/bigdecimal.rb +58 -0
  18. data/lib/json/add/complex.rb +51 -0
  19. data/lib/json/add/core.rb +12 -0
  20. data/lib/json/add/date.rb +54 -0
  21. data/lib/json/add/date_time.rb +67 -0
  22. data/lib/json/add/exception.rb +49 -0
  23. data/lib/json/add/ostruct.rb +54 -0
  24. data/lib/json/add/range.rb +54 -0
  25. data/lib/json/add/rational.rb +49 -0
  26. data/lib/json/add/regexp.rb +48 -0
  27. data/lib/json/add/set.rb +48 -0
  28. data/lib/json/add/struct.rb +52 -0
  29. data/lib/json/add/symbol.rb +48 -0
  30. data/lib/json/add/time.rb +59 -0
  31. data/lib/json/common.rb +588 -74
  32. data/lib/json/ext.rb +3 -1
  33. data/lib/json/generic_object.rb +75 -0
  34. data/lib/json/pure/generator.rb +311 -119
  35. data/lib/json/pure/parser.rb +182 -55
  36. data/lib/json/pure.rb +5 -65
  37. data/lib/json/version.rb +2 -1
  38. data/lib/json.rb +583 -196
  39. metadata +78 -137
  40. data/CHANGES +0 -25
  41. data/GPL +0 -340
  42. data/README +0 -77
  43. data/Rakefile +0 -250
  44. data/TODO +0 -1
  45. data/VERSION +0 -1
  46. data/benchmarks/benchmark.txt +0 -133
  47. data/benchmarks/benchmark_generator.rb +0 -44
  48. data/benchmarks/benchmark_parser.rb +0 -22
  49. data/benchmarks/benchmark_rails.rb +0 -26
  50. data/bin/edit_json.rb +0 -11
  51. data/data/example.json +0 -1
  52. data/data/index.html +0 -37
  53. data/data/prototype.js +0 -2515
  54. data/ext/json/ext/generator/Makefile +0 -149
  55. data/ext/json/ext/generator/unicode.c +0 -184
  56. data/ext/json/ext/generator/unicode.h +0 -40
  57. data/ext/json/ext/parser/Makefile +0 -149
  58. data/ext/json/ext/parser/unicode.c +0 -156
  59. data/ext/json/ext/parser/unicode.h +0 -44
  60. data/install.rb +0 -26
  61. data/lib/json/Array.xpm +0 -21
  62. data/lib/json/FalseClass.xpm +0 -21
  63. data/lib/json/Hash.xpm +0 -21
  64. data/lib/json/Key.xpm +0 -73
  65. data/lib/json/NilClass.xpm +0 -21
  66. data/lib/json/Numeric.xpm +0 -28
  67. data/lib/json/String.xpm +0 -96
  68. data/lib/json/TrueClass.xpm +0 -21
  69. data/lib/json/editor.rb +0 -1207
  70. data/lib/json/json.xpm +0 -1499
  71. data/tests/fixtures/fail1.json +0 -1
  72. data/tests/fixtures/fail10.json +0 -1
  73. data/tests/fixtures/fail11.json +0 -1
  74. data/tests/fixtures/fail12.json +0 -1
  75. data/tests/fixtures/fail13.json +0 -1
  76. data/tests/fixtures/fail14.json +0 -1
  77. data/tests/fixtures/fail15.json +0 -1
  78. data/tests/fixtures/fail16.json +0 -1
  79. data/tests/fixtures/fail17.json +0 -1
  80. data/tests/fixtures/fail19.json +0 -1
  81. data/tests/fixtures/fail2.json +0 -1
  82. data/tests/fixtures/fail20.json +0 -1
  83. data/tests/fixtures/fail21.json +0 -1
  84. data/tests/fixtures/fail22.json +0 -1
  85. data/tests/fixtures/fail23.json +0 -1
  86. data/tests/fixtures/fail24.json +0 -1
  87. data/tests/fixtures/fail25.json +0 -1
  88. data/tests/fixtures/fail26.json +0 -1
  89. data/tests/fixtures/fail27.json +0 -2
  90. data/tests/fixtures/fail28.json +0 -2
  91. data/tests/fixtures/fail3.json +0 -1
  92. data/tests/fixtures/fail4.json +0 -1
  93. data/tests/fixtures/fail5.json +0 -1
  94. data/tests/fixtures/fail6.json +0 -1
  95. data/tests/fixtures/fail7.json +0 -1
  96. data/tests/fixtures/fail8.json +0 -1
  97. data/tests/fixtures/fail9.json +0 -1
  98. data/tests/fixtures/pass1.json +0 -56
  99. data/tests/fixtures/pass18.json +0 -1
  100. data/tests/fixtures/pass2.json +0 -1
  101. data/tests/fixtures/pass3.json +0 -6
  102. data/tests/runner.rb +0 -24
  103. data/tests/test_json.rb +0 -235
  104. data/tests/test_json_addition.rb +0 -94
  105. data/tests/test_json_fixtures.rb +0 -30
  106. data/tests/test_json_generate.rb +0 -81
  107. data/tests/test_json_unicode.rb +0 -55
  108. data/tools/fuzz.rb +0 -133
  109. data/tools/server.rb +0 -62
data/lib/json.rb CHANGED
@@ -1,202 +1,589 @@
1
+ #frozen_string_literal: false
1
2
  require 'json/common'
2
- # = json - JSON for Ruby
3
- #
4
- # == Description
5
- #
6
- # This is a implementation of the JSON specification according to RFC 4627
7
- # (http://www.ietf.org/rfc/rfc4627.txt). Starting from version 1.0.0 on there
8
- # will be two variants available:
9
- #
10
- # * A pure ruby variant, that relies on the iconv and the stringscan
11
- # extensions, which are both part of the ruby standard library.
12
- # * The quite a bit faster C extension variant, which is in parts implemented
13
- # in C and comes with its own unicode conversion functions and a parser
14
- # generated by the ragel state machine compiler
15
- # (http://www.cs.queensu.ca/~thurston/ragel).
16
- #
17
- # Both variants of the JSON generator escape all non-ASCII an control
18
- # characters with \uXXXX escape sequences, and support UTF-16 surrogate pairs
19
- # in order to be able to generate the whole range of unicode code points. This
20
- # means that generated JSON text is encoded as UTF-8 (because ASCII is a subset
21
- # of UTF-8) and at the same time avoids decoding problems for receiving
22
- # endpoints, that don't expect UTF-8 encoded texts. On the negative side this
23
- # may lead to a bit longer strings than necessarry.
24
- #
25
- # All strings, that are to be encoded as JSON strings, should be UTF-8 byte
26
- # sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
27
- # encoded, please use the to_json_raw_object method of String (which produces
28
- # an object, that contains a byte array) and decode the result on the receiving
29
- # endpoint.
30
- #
31
- # == Author
32
- #
33
- # Florian Frank <mailto:flori@ping.de>
34
- #
35
- # == License
36
- #
37
- # This is free software; you can redistribute it and/or modify it under the
38
- # terms of the GNU General Public License Version 2 as published by the Free
39
- # Software Foundation: www.gnu.org/copyleft/gpl.html
40
- #
41
- # == Download
42
- #
43
- # The latest version of this library can be downloaded at
44
- #
45
- # * http://rubyforge.org/frs?group_id=953
46
- #
47
- # Online Documentation should be located at
48
- #
49
- # * http://json.rubyforge.org
50
- #
51
- # == Speed Comparisons
52
- #
53
- # I have created some benchmark results (see the benchmarks subdir of the
54
- # package) for the JSON-Parser to estimate the speed up in the C extension:
55
- #
56
- # JSON::Pure::Parser:: 28.90 calls/second
57
- # JSON::Ext::Parser:: 505.50 calls/second
58
- #
59
- # This is ca. <b>17.5</b> times the speed of the pure Ruby implementation.
60
- #
61
- # I have benchmarked the JSON-Generator as well. This generates a few more
62
- # values, because there are different modes, that also influence the achieved
63
- # speed:
64
- #
65
- # * JSON::Pure::Generator:
66
- # generate:: 35.06 calls/second
67
- # pretty_generate:: 34.00 calls/second
68
- # fast_generate:: 41.06 calls/second
69
- #
70
- # * JSON::Ext::Generator:
71
- # generate:: 492.11 calls/second
72
- # pretty_generate:: 348.85 calls/second
73
- # fast_generate:: 541.60 calls/second
74
- #
75
- # * Speedup Ext/Pure:
76
- # generate safe:: 14.0 times
77
- # generate pretty:: 10.3 times
78
- # generate fast:: 13.2 times
79
- #
80
- # The rails framework includes a generator as well, also it seems to be rather
81
- # slow: I measured only 23.87 calls/second which is slower than any of my pure
82
- # generator results. Here a comparison of the different speedups with the Rails
83
- # measurement as the divisor:
84
- #
85
- # * Speedup Pure/Rails:
86
- # generate safe:: 1.5 times
87
- # generate pretty:: 1.4 times
88
- # generate fast:: 1.7 times
89
- #
90
- # * Speedup Ext/Rails:
91
- # generate safe:: 20.6 times
92
- # generate pretty:: 14.6 times
93
- # generate fast:: 22.7 times
94
- #
95
- # To achieve the fastest JSON text output, you can use the
96
- # fast_generate/fast_unparse methods. Beware, that this will disable the
97
- # checking for circular Ruby data structures, which may cause JSON to go into
98
- # an infinite loop.
99
- #
100
- # == Examples
101
- #
102
- # To create a JSON text from a ruby data structure, you
103
- # can call JSON.generate (or JSON.unparse) like that:
104
- #
105
- # json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
106
- # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
107
- #
108
- # It's also possible to call the #to_json method directly.
109
- #
110
- # json = [1, 2, {"a"=>3.141}, false, true, nil, 4..10].to_json
111
- # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
112
- #
113
- # To create a valid JSON text you have to make sure, that the output is
114
- # embedded in either a JSON array [] or a JSON object {}. The easiest way to do
115
- # this, is by putting your values in a Ruby Array or Hash instance.
116
- #
117
- # To get back a ruby data structure from a JSON text, you have to call
118
- # JSON.parse on it:
119
- #
120
- # JSON.parse json
121
- # # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
122
- #
123
- # Note, that the range from the original data structure is a simple
124
- # string now. The reason for this is, that JSON doesn't support ranges
125
- # or arbitrary classes. In this case the json library falls back to call
126
- # Object#to_json, which is the same as #to_s.to_json.
127
- #
128
- # It's possible to extend JSON to support serialization of arbitrary classes by
129
- # simply implementing a more specialized version of the #to_json method, that
130
- # should return a JSON object (a hash converted to JSON with #to_json)
131
- # like this (don't forget the *a for all the arguments):
132
- #
133
- # class Range
134
- # def to_json(*a)
135
- # {
136
- # 'json_class' => self.class.name, # = 'Range'
137
- # 'data' => [ first, last, exclude_end? ]
138
- # }.to_json(*a)
139
- # end
140
- # end
141
- #
142
- # The hash key 'json_class' is the class, that will be asked to deserialize the
143
- # JSON representation later. In this case it's 'Range', but any namespace of
144
- # the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
145
- # used to store the necessary data to configure the object to be deserialized.
146
- #
147
- # If a the key 'json_class' is found in a JSON object, the JSON parser checks
148
- # if the given class responds to the json_create class method. If so, it is
149
- # called with the JSON object converted to a Ruby hash. So a range can
150
- # be deserialized by implementing Range.json_create like this:
151
- #
152
- # class Range
153
- # def self.json_create(o)
154
- # new(*o['data'])
155
- # end
156
- # end
157
- #
158
- # Now it possible to serialize/deserialize ranges as well:
159
- #
160
- # json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
161
- # # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
162
- # JSON.parse json
163
- # # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
164
- #
165
- # JSON.generate always creates the shortest possible string representation of a
166
- # ruby data structure in one line. This good for data storage or network
167
- # protocols, but not so good for humans to read. Fortunately there's also
168
- # JSON.pretty_generate (or JSON.pretty_generate) that creates a more
169
- # readable output:
170
- #
171
- # puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
172
- # [
173
- # 1,
174
- # 2,
175
- # {
176
- # "a": 3.141
177
- # },
178
- # false,
179
- # true,
180
- # null,
181
- # {
182
- # "json_class": "Range",
183
- # "data": [
184
- # 4,
185
- # 10,
186
- # false
187
- # ]
188
- # }
189
- # ]
190
- #
191
- # There are also the methods Kernel#j for unparse, and Kernel#jj for
192
- # pretty_unparse output to the console, that work analogous to Core Ruby's p
193
- # and the pp library's pp methods.
194
- #
195
- # The script tools/server.rb contains a small example if you want to test, how
196
- # receiving a JSON object from a webrick server in your browser with the
197
- # javasript prototype library (http://www.prototypejs.org) works.
3
+
4
+ ##
5
+ # = JavaScript \Object Notation (\JSON)
6
+ #
7
+ # \JSON is a lightweight data-interchange format.
8
+ #
9
+ # A \JSON value is one of the following:
10
+ # - Double-quoted text: <tt>"foo"</tt>.
11
+ # - Number: +1+, +1.0+, +2.0e2+.
12
+ # - Boolean: +true+, +false+.
13
+ # - Null: +null+.
14
+ # - \Array: an ordered list of values, enclosed by square brackets:
15
+ # ["foo", 1, 1.0, 2.0e2, true, false, null]
16
+ #
17
+ # - \Object: a collection of name/value pairs, enclosed by curly braces;
18
+ # each name is double-quoted text;
19
+ # the values may be any \JSON values:
20
+ # {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
21
+ #
22
+ # A \JSON array or object may contain nested arrays, objects, and scalars
23
+ # to any depth:
24
+ # {"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
25
+ # [{"foo": 0, "bar": 1}, ["baz", 2]]
26
+ #
27
+ # == Using \Module \JSON
28
+ #
29
+ # To make module \JSON available in your code, begin with:
30
+ # require 'json'
31
+ #
32
+ # All examples here assume that this has been done.
33
+ #
34
+ # === Parsing \JSON
35
+ #
36
+ # You can parse a \String containing \JSON data using
37
+ # either of two methods:
38
+ # - <tt>JSON.parse(source, opts)</tt>
39
+ # - <tt>JSON.parse!(source, opts)</tt>
40
+ #
41
+ # where
42
+ # - +source+ is a Ruby object.
43
+ # - +opts+ is a \Hash object containing options
44
+ # that control both input allowed and output formatting.
45
+ #
46
+ # The difference between the two methods
47
+ # is that JSON.parse! omits some checks
48
+ # and may not be safe for some +source+ data;
49
+ # use it only for data from trusted sources.
50
+ # Use the safer method JSON.parse for less trusted sources.
51
+ #
52
+ # ==== Parsing \JSON Arrays
53
+ #
54
+ # When +source+ is a \JSON array, JSON.parse by default returns a Ruby \Array:
55
+ # json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
56
+ # ruby = JSON.parse(json)
57
+ # ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
58
+ # ruby.class # => Array
59
+ #
60
+ # The \JSON array may contain nested arrays, objects, and scalars
61
+ # to any depth:
62
+ # json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
63
+ # JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]
64
+ #
65
+ # ==== Parsing \JSON \Objects
66
+ #
67
+ # When the source is a \JSON object, JSON.parse by default returns a Ruby \Hash:
68
+ # json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
69
+ # ruby = JSON.parse(json)
70
+ # ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
71
+ # ruby.class # => Hash
72
+ #
73
+ # The \JSON object may contain nested arrays, objects, and scalars
74
+ # to any depth:
75
+ # json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
76
+ # JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
77
+ #
78
+ # ==== Parsing \JSON Scalars
79
+ #
80
+ # When the source is a \JSON scalar (not an array or object),
81
+ # JSON.parse returns a Ruby scalar.
82
+ #
83
+ # \String:
84
+ # ruby = JSON.parse('"foo"')
85
+ # ruby # => 'foo'
86
+ # ruby.class # => String
87
+ # \Integer:
88
+ # ruby = JSON.parse('1')
89
+ # ruby # => 1
90
+ # ruby.class # => Integer
91
+ # \Float:
92
+ # ruby = JSON.parse('1.0')
93
+ # ruby # => 1.0
94
+ # ruby.class # => Float
95
+ # ruby = JSON.parse('2.0e2')
96
+ # ruby # => 200
97
+ # ruby.class # => Float
98
+ # Boolean:
99
+ # ruby = JSON.parse('true')
100
+ # ruby # => true
101
+ # ruby.class # => TrueClass
102
+ # ruby = JSON.parse('false')
103
+ # ruby # => false
104
+ # ruby.class # => FalseClass
105
+ # Null:
106
+ # ruby = JSON.parse('null')
107
+ # ruby # => nil
108
+ # ruby.class # => NilClass
109
+ #
110
+ # ==== Parsing Options
111
+ #
112
+ # ====== Input Options
113
+ #
114
+ # Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
115
+ # defaults to +100+; specify +false+ to disable depth checking.
116
+ #
117
+ # With the default, +false+:
118
+ # source = '[0, [1, [2, [3]]]]'
119
+ # ruby = JSON.parse(source)
120
+ # ruby # => [0, [1, [2, [3]]]]
121
+ # Too deep:
122
+ # # Raises JSON::NestingError (nesting of 2 is too deep):
123
+ # JSON.parse(source, {max_nesting: 1})
124
+ # Bad value:
125
+ # # Raises TypeError (wrong argument type Symbol (expected Fixnum)):
126
+ # JSON.parse(source, {max_nesting: :foo})
127
+ #
128
+ # ---
129
+ #
130
+ # Option +allow_nan+ (boolean) specifies whether to allow
131
+ # NaN, Infinity, and MinusInfinity in +source+;
132
+ # defaults to +false+.
133
+ #
134
+ # With the default, +false+:
135
+ # # Raises JSON::ParserError (225: unexpected token at '[NaN]'):
136
+ # JSON.parse('[NaN]')
137
+ # # Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
138
+ # JSON.parse('[Infinity]')
139
+ # # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
140
+ # JSON.parse('[-Infinity]')
141
+ # Allow:
142
+ # source = '[NaN, Infinity, -Infinity]'
143
+ # ruby = JSON.parse(source, {allow_nan: true})
144
+ # ruby # => [NaN, Infinity, -Infinity]
145
+ #
146
+ # ====== Output Options
147
+ #
148
+ # Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
149
+ # should be Symbols;
150
+ # defaults to +false+ (use Strings).
151
+ #
152
+ # With the default, +false+:
153
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
154
+ # ruby = JSON.parse(source)
155
+ # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
156
+ # Use Symbols:
157
+ # ruby = JSON.parse(source, {symbolize_names: true})
158
+ # ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
159
+ #
160
+ # ---
161
+ #
162
+ # Option +object_class+ (\Class) specifies the Ruby class to be used
163
+ # for each \JSON object;
164
+ # defaults to \Hash.
165
+ #
166
+ # With the default, \Hash:
167
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
168
+ # ruby = JSON.parse(source)
169
+ # ruby.class # => Hash
170
+ # Use class \OpenStruct:
171
+ # ruby = JSON.parse(source, {object_class: OpenStruct})
172
+ # ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
173
+ #
174
+ # ---
175
+ #
176
+ # Option +array_class+ (\Class) specifies the Ruby class to be used
177
+ # for each \JSON array;
178
+ # defaults to \Array.
179
+ #
180
+ # With the default, \Array:
181
+ # source = '["foo", 1.0, true, false, null]'
182
+ # ruby = JSON.parse(source)
183
+ # ruby.class # => Array
184
+ # Use class \Set:
185
+ # ruby = JSON.parse(source, {array_class: Set})
186
+ # ruby # => #<Set: {"foo", 1.0, true, false, nil}>
187
+ #
188
+ # ---
189
+ #
190
+ # Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
191
+ # See {\JSON Additions}[#module-JSON-label-JSON+Additions].
192
+ #
193
+ # === Generating \JSON
194
+ #
195
+ # To generate a Ruby \String containing \JSON data,
196
+ # use method <tt>JSON.generate(source, opts)</tt>, where
197
+ # - +source+ is a Ruby object.
198
+ # - +opts+ is a \Hash object containing options
199
+ # that control both input allowed and output formatting.
200
+ #
201
+ # ==== Generating \JSON from Arrays
202
+ #
203
+ # When the source is a Ruby \Array, JSON.generate returns
204
+ # a \String containing a \JSON array:
205
+ # ruby = [0, 's', :foo]
206
+ # json = JSON.generate(ruby)
207
+ # json # => '[0,"s","foo"]'
208
+ #
209
+ # The Ruby \Array array may contain nested arrays, hashes, and scalars
210
+ # to any depth:
211
+ # ruby = [0, [1, 2], {foo: 3, bar: 4}]
212
+ # json = JSON.generate(ruby)
213
+ # json # => '[0,[1,2],{"foo":3,"bar":4}]'
214
+ #
215
+ # ==== Generating \JSON from Hashes
216
+ #
217
+ # When the source is a Ruby \Hash, JSON.generate returns
218
+ # a \String containing a \JSON object:
219
+ # ruby = {foo: 0, bar: 's', baz: :bat}
220
+ # json = JSON.generate(ruby)
221
+ # json # => '{"foo":0,"bar":"s","baz":"bat"}'
222
+ #
223
+ # The Ruby \Hash array may contain nested arrays, hashes, and scalars
224
+ # to any depth:
225
+ # ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
226
+ # json = JSON.generate(ruby)
227
+ # json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'
228
+ #
229
+ # ==== Generating \JSON from Other Objects
230
+ #
231
+ # When the source is neither an \Array nor a \Hash,
232
+ # the generated \JSON data depends on the class of the source.
233
+ #
234
+ # When the source is a Ruby \Integer or \Float, JSON.generate returns
235
+ # a \String containing a \JSON number:
236
+ # JSON.generate(42) # => '42'
237
+ # JSON.generate(0.42) # => '0.42'
238
+ #
239
+ # When the source is a Ruby \String, JSON.generate returns
240
+ # a \String containing a \JSON string (with double-quotes):
241
+ # JSON.generate('A string') # => '"A string"'
242
+ #
243
+ # When the source is +true+, +false+ or +nil+, JSON.generate returns
244
+ # a \String containing the corresponding \JSON token:
245
+ # JSON.generate(true) # => 'true'
246
+ # JSON.generate(false) # => 'false'
247
+ # JSON.generate(nil) # => 'null'
248
+ #
249
+ # When the source is none of the above, JSON.generate returns
250
+ # a \String containing a \JSON string representation of the source:
251
+ # JSON.generate(:foo) # => '"foo"'
252
+ # JSON.generate(Complex(0, 0)) # => '"0+0i"'
253
+ # JSON.generate(Dir.new('.')) # => '"#<Dir>"'
254
+ #
255
+ # ==== Generating Options
256
+ #
257
+ # ====== Input Options
258
+ #
259
+ # Option +allow_nan+ (boolean) specifies whether
260
+ # +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
261
+ # defaults to +false+.
262
+ #
263
+ # With the default, +false+:
264
+ # # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
265
+ # JSON.generate(JSON::NaN)
266
+ # # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
267
+ # JSON.generate(JSON::Infinity)
268
+ # # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
269
+ # JSON.generate(JSON::MinusInfinity)
270
+ #
271
+ # Allow:
272
+ # ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
273
+ # JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
274
+ #
275
+ # ---
276
+ #
277
+ # Option +max_nesting+ (\Integer) specifies the maximum nesting depth
278
+ # in +obj+; defaults to +100+.
279
+ #
280
+ # With the default, +100+:
281
+ # obj = [[[[[[0]]]]]]
282
+ # JSON.generate(obj) # => '[[[[[[0]]]]]]'
283
+ #
284
+ # Too deep:
285
+ # # Raises JSON::NestingError (nesting of 2 is too deep):
286
+ # JSON.generate(obj, max_nesting: 2)
287
+ #
288
+ # ====== Escaping Options
289
+ #
290
+ # Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt>
291
+ # and <tt>'/'</tt> should be escaped as to make the JSON object safe to interpolate in script
292
+ # tags.
293
+ #
294
+ # Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range
295
+ # should be escaped.
296
+ #
297
+ # ====== Output Options
298
+ #
299
+ # The default formatting options generate the most compact
300
+ # \JSON data, all on one line and with no whitespace.
301
+ #
302
+ # You can use these formatting options to generate
303
+ # \JSON data in a more open format, using whitespace.
304
+ # See also JSON.pretty_generate.
305
+ #
306
+ # - Option +array_nl+ (\String) specifies a string (usually a newline)
307
+ # to be inserted after each \JSON array; defaults to the empty \String, <tt>''</tt>.
308
+ # - Option +object_nl+ (\String) specifies a string (usually a newline)
309
+ # to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
310
+ # - Option +indent+ (\String) specifies the string (usually spaces) to be
311
+ # used for indentation; defaults to the empty \String, <tt>''</tt>;
312
+ # defaults to the empty \String, <tt>''</tt>;
313
+ # has no effect unless options +array_nl+ or +object_nl+ specify newlines.
314
+ # - Option +space+ (\String) specifies a string (usually a space) to be
315
+ # inserted after the colon in each \JSON object's pair;
316
+ # defaults to the empty \String, <tt>''</tt>.
317
+ # - Option +space_before+ (\String) specifies a string (usually a space) to be
318
+ # inserted before the colon in each \JSON object's pair;
319
+ # defaults to the empty \String, <tt>''</tt>.
320
+ #
321
+ # In this example, +obj+ is used first to generate the shortest
322
+ # \JSON data (no whitespace), then again with all formatting options
323
+ # specified:
324
+ #
325
+ # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
326
+ # json = JSON.generate(obj)
327
+ # puts 'Compact:', json
328
+ # opts = {
329
+ # array_nl: "\n",
330
+ # object_nl: "\n",
331
+ # indent: ' ',
332
+ # space_before: ' ',
333
+ # space: ' '
334
+ # }
335
+ # puts 'Open:', JSON.generate(obj, opts)
336
+ #
337
+ # Output:
338
+ # Compact:
339
+ # {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
340
+ # Open:
341
+ # {
342
+ # "foo" : [
343
+ # "bar",
344
+ # "baz"
345
+ # ],
346
+ # "bat" : {
347
+ # "bam" : 0,
348
+ # "bad" : 1
349
+ # }
350
+ # }
351
+ #
352
+ # == \JSON Additions
353
+ #
354
+ # When you "round trip" a non-\String object from Ruby to \JSON and back,
355
+ # you have a new \String, instead of the object you began with:
356
+ # ruby0 = Range.new(0, 2)
357
+ # json = JSON.generate(ruby0)
358
+ # json # => '0..2"'
359
+ # ruby1 = JSON.parse(json)
360
+ # ruby1 # => '0..2'
361
+ # ruby1.class # => String
362
+ #
363
+ # You can use \JSON _additions_ to preserve the original object.
364
+ # The addition is an extension of a ruby class, so that:
365
+ # - \JSON.generate stores more information in the \JSON string.
366
+ # - \JSON.parse, called with option +create_additions+,
367
+ # uses that information to create a proper Ruby object.
368
+ #
369
+ # This example shows a \Range being generated into \JSON
370
+ # and parsed back into Ruby, both without and with
371
+ # the addition for \Range:
372
+ # ruby = Range.new(0, 2)
373
+ # # This passage does not use the addition for Range.
374
+ # json0 = JSON.generate(ruby)
375
+ # ruby0 = JSON.parse(json0)
376
+ # # This passage uses the addition for Range.
377
+ # require 'json/add/range'
378
+ # json1 = JSON.generate(ruby)
379
+ # ruby1 = JSON.parse(json1, create_additions: true)
380
+ # # Make a nice display.
381
+ # display = <<EOT
382
+ # Generated JSON:
383
+ # Without addition: #{json0} (#{json0.class})
384
+ # With addition: #{json1} (#{json1.class})
385
+ # Parsed JSON:
386
+ # Without addition: #{ruby0.inspect} (#{ruby0.class})
387
+ # With addition: #{ruby1.inspect} (#{ruby1.class})
388
+ # EOT
389
+ # puts display
390
+ #
391
+ # This output shows the different results:
392
+ # Generated JSON:
393
+ # Without addition: "0..2" (String)
394
+ # With addition: {"json_class":"Range","a":[0,2,false]} (String)
395
+ # Parsed JSON:
396
+ # Without addition: "0..2" (String)
397
+ # With addition: 0..2 (Range)
398
+ #
399
+ # The \JSON module includes additions for certain classes.
400
+ # You can also craft custom additions.
401
+ # See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
402
+ #
403
+ # === Built-in Additions
404
+ #
405
+ # The \JSON module includes additions for certain classes.
406
+ # To use an addition, +require+ its source:
407
+ # - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
408
+ # - Complex: <tt>require 'json/add/complex'</tt>
409
+ # - Date: <tt>require 'json/add/date'</tt>
410
+ # - DateTime: <tt>require 'json/add/date_time'</tt>
411
+ # - Exception: <tt>require 'json/add/exception'</tt>
412
+ # - OpenStruct: <tt>require 'json/add/ostruct'</tt>
413
+ # - Range: <tt>require 'json/add/range'</tt>
414
+ # - Rational: <tt>require 'json/add/rational'</tt>
415
+ # - Regexp: <tt>require 'json/add/regexp'</tt>
416
+ # - Set: <tt>require 'json/add/set'</tt>
417
+ # - Struct: <tt>require 'json/add/struct'</tt>
418
+ # - Symbol: <tt>require 'json/add/symbol'</tt>
419
+ # - Time: <tt>require 'json/add/time'</tt>
420
+ #
421
+ # To reduce punctuation clutter, the examples below
422
+ # show the generated \JSON via +puts+, rather than the usual +inspect+,
423
+ #
424
+ # \BigDecimal:
425
+ # require 'json/add/bigdecimal'
426
+ # ruby0 = BigDecimal(0) # 0.0
427
+ # json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
428
+ # ruby1 = JSON.parse(json, create_additions: true) # 0.0
429
+ # ruby1.class # => BigDecimal
430
+ #
431
+ # \Complex:
432
+ # require 'json/add/complex'
433
+ # ruby0 = Complex(1+0i) # 1+0i
434
+ # json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
435
+ # ruby1 = JSON.parse(json, create_additions: true) # 1+0i
436
+ # ruby1.class # Complex
437
+ #
438
+ # \Date:
439
+ # require 'json/add/date'
440
+ # ruby0 = Date.today # 2020-05-02
441
+ # json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
442
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
443
+ # ruby1.class # Date
444
+ #
445
+ # \DateTime:
446
+ # require 'json/add/date_time'
447
+ # ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
448
+ # 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}
449
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
450
+ # ruby1.class # DateTime
451
+ #
452
+ # \Exception (and its subclasses including \RuntimeError):
453
+ # require 'json/add/exception'
454
+ # ruby0 = Exception.new('A message') # A message
455
+ # json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
456
+ # ruby1 = JSON.parse(json, create_additions: true) # A message
457
+ # ruby1.class # Exception
458
+ # ruby0 = RuntimeError.new('Another message') # Another message
459
+ # json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
460
+ # ruby1 = JSON.parse(json, create_additions: true) # Another message
461
+ # ruby1.class # RuntimeError
462
+ #
463
+ # \OpenStruct:
464
+ # require 'json/add/ostruct'
465
+ # ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
466
+ # json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
467
+ # ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
468
+ # ruby1.class # OpenStruct
469
+ #
470
+ # \Range:
471
+ # require 'json/add/range'
472
+ # ruby0 = Range.new(0, 2) # 0..2
473
+ # json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
474
+ # ruby1 = JSON.parse(json, create_additions: true) # 0..2
475
+ # ruby1.class # Range
476
+ #
477
+ # \Rational:
478
+ # require 'json/add/rational'
479
+ # ruby0 = Rational(1, 3) # 1/3
480
+ # json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
481
+ # ruby1 = JSON.parse(json, create_additions: true) # 1/3
482
+ # ruby1.class # Rational
483
+ #
484
+ # \Regexp:
485
+ # require 'json/add/regexp'
486
+ # ruby0 = Regexp.new('foo') # (?-mix:foo)
487
+ # json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
488
+ # ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
489
+ # ruby1.class # Regexp
490
+ #
491
+ # \Set:
492
+ # require 'json/add/set'
493
+ # ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
494
+ # json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
495
+ # ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
496
+ # ruby1.class # Set
497
+ #
498
+ # \Struct:
499
+ # require 'json/add/struct'
500
+ # Customer = Struct.new(:name, :address) # Customer
501
+ # ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
502
+ # json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
503
+ # ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
504
+ # ruby1.class # Customer
505
+ #
506
+ # \Symbol:
507
+ # require 'json/add/symbol'
508
+ # ruby0 = :foo # foo
509
+ # json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
510
+ # ruby1 = JSON.parse(json, create_additions: true) # foo
511
+ # ruby1.class # Symbol
512
+ #
513
+ # \Time:
514
+ # require 'json/add/time'
515
+ # ruby0 = Time.now # 2020-05-02 11:28:26 -0500
516
+ # json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
517
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
518
+ # ruby1.class # Time
519
+ #
520
+ #
521
+ # === Custom \JSON Additions
522
+ #
523
+ # In addition to the \JSON additions provided,
524
+ # you can craft \JSON additions of your own,
525
+ # either for Ruby built-in classes or for user-defined classes.
526
+ #
527
+ # Here's a user-defined class +Foo+:
528
+ # class Foo
529
+ # attr_accessor :bar, :baz
530
+ # def initialize(bar, baz)
531
+ # self.bar = bar
532
+ # self.baz = baz
533
+ # end
534
+ # end
535
+ #
536
+ # Here's the \JSON addition for it:
537
+ # # Extend class Foo with JSON addition.
538
+ # class Foo
539
+ # # Serialize Foo object with its class name and arguments
540
+ # def to_json(*args)
541
+ # {
542
+ # JSON.create_id => self.class.name,
543
+ # 'a' => [ bar, baz ]
544
+ # }.to_json(*args)
545
+ # end
546
+ # # Deserialize JSON string by constructing new Foo object with arguments.
547
+ # def self.json_create(object)
548
+ # new(*object['a'])
549
+ # end
550
+ # end
551
+ #
552
+ # Demonstration:
553
+ # require 'json'
554
+ # # This Foo object has no custom addition.
555
+ # foo0 = Foo.new(0, 1)
556
+ # json0 = JSON.generate(foo0)
557
+ # obj0 = JSON.parse(json0)
558
+ # # Lood the custom addition.
559
+ # require_relative 'foo_addition'
560
+ # # This foo has the custom addition.
561
+ # foo1 = Foo.new(0, 1)
562
+ # json1 = JSON.generate(foo1)
563
+ # obj1 = JSON.parse(json1, create_additions: true)
564
+ # # Make a nice display.
565
+ # display = <<EOT
566
+ # Generated JSON:
567
+ # Without custom addition: #{json0} (#{json0.class})
568
+ # With custom addition: #{json1} (#{json1.class})
569
+ # Parsed JSON:
570
+ # Without custom addition: #{obj0.inspect} (#{obj0.class})
571
+ # With custom addition: #{obj1.inspect} (#{obj1.class})
572
+ # EOT
573
+ # puts display
574
+ #
575
+ # Output:
576
+ #
577
+ # Generated JSON:
578
+ # Without custom addition: "#<Foo:0x0000000006534e80>" (String)
579
+ # With custom addition: {"json_class":"Foo","a":[0,1]} (String)
580
+ # Parsed JSON:
581
+ # Without custom addition: "#<Foo:0x0000000006534e80>" (String)
582
+ # With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
198
583
  #
199
584
  module JSON
585
+ require 'json/version'
586
+
200
587
  begin
201
588
  require 'json/ext'
202
589
  rescue LoadError