json 2.21.2 → 3.0.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.
- checksums.yaml +4 -4
- data/CHANGES.md +55 -1
- data/README.md +4 -84
- data/ext/json/ext/generator/generator.c +32 -38
- data/ext/json/ext/json.h +13 -0
- data/ext/json/ext/parser/parser.c +80 -84
- data/lib/json/common.rb +142 -401
- data/lib/json/ext/generator/state.rb +0 -27
- data/lib/json/ext.rb +0 -2
- data/lib/json/truffle_ruby/generator.rb +38 -80
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +43 -295
- metadata +1 -17
- data/lib/json/add/bigdecimal.rb +0 -58
- data/lib/json/add/complex.rb +0 -51
- data/lib/json/add/core.rb +0 -13
- data/lib/json/add/date.rb +0 -54
- data/lib/json/add/date_time.rb +0 -67
- data/lib/json/add/exception.rb +0 -49
- data/lib/json/add/ostruct.rb +0 -54
- data/lib/json/add/range.rb +0 -54
- data/lib/json/add/rational.rb +0 -49
- data/lib/json/add/regexp.rb +0 -48
- data/lib/json/add/set.rb +0 -48
- data/lib/json/add/string.rb +0 -35
- data/lib/json/add/struct.rb +0 -52
- data/lib/json/add/symbol.rb +0 -52
- data/lib/json/add/time.rb +0 -52
- data/lib/json/generic_object.rb +0 -67
data/lib/json.rb
CHANGED
|
@@ -44,13 +44,13 @@ require 'json/common'
|
|
|
44
44
|
#
|
|
45
45
|
# You can parse a \String containing \JSON data using
|
|
46
46
|
# either of two methods:
|
|
47
|
-
# - <tt>JSON.parse(source, opts)</tt>
|
|
48
|
-
# - <tt>JSON.parse!(source, opts)</tt>
|
|
47
|
+
# - <tt>JSON.parse(source, **opts)</tt>
|
|
48
|
+
# - <tt>JSON.parse!(source, **opts)</tt>
|
|
49
49
|
#
|
|
50
50
|
# where
|
|
51
51
|
# - +source+ is a Ruby object.
|
|
52
|
-
# - +opts+
|
|
53
|
-
#
|
|
52
|
+
# - +opts+ are keyword arguments that control both input
|
|
53
|
+
# allowed and output formatting.
|
|
54
54
|
#
|
|
55
55
|
# The difference between the two methods
|
|
56
56
|
# is that JSON.parse! omits some checks
|
|
@@ -102,7 +102,7 @@ require 'json/common'
|
|
|
102
102
|
# ruby # => 1.0
|
|
103
103
|
# ruby.class # => Float
|
|
104
104
|
# ruby = JSON.parse('2.0e2')
|
|
105
|
-
# ruby # => 200
|
|
105
|
+
# ruby # => 200.0
|
|
106
106
|
# ruby.class # => Float
|
|
107
107
|
# Boolean:
|
|
108
108
|
# ruby = JSON.parse('true')
|
|
@@ -131,28 +131,22 @@ require 'json/common'
|
|
|
131
131
|
# ruby # => [0, [1, [2, [3]]]]
|
|
132
132
|
# Too deep:
|
|
133
133
|
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
134
|
-
# JSON.parse(source,
|
|
134
|
+
# JSON.parse(source, max_nesting: 1)
|
|
135
135
|
# Bad value:
|
|
136
|
-
# # Raises TypeError (
|
|
137
|
-
# JSON.parse(source,
|
|
136
|
+
# # Raises TypeError (no implicit conversion of Symbol into Integer):
|
|
137
|
+
# JSON.parse(source, max_nesting: :foo)
|
|
138
138
|
#
|
|
139
139
|
# ---
|
|
140
140
|
#
|
|
141
141
|
# Option +allow_duplicate_key+ specifies whether duplicate keys in objects
|
|
142
142
|
# should be ignored or cause an error to be raised:
|
|
143
143
|
#
|
|
144
|
-
# When
|
|
145
|
-
#
|
|
146
|
-
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
147
|
-
# # warning: detected duplicate keys in JSON object.
|
|
148
|
-
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
144
|
+
# When set to +false+, the default:
|
|
145
|
+
# JSON.parse('{"a": 1, "a": 2}') # duplicate key "a" at line 1 column 1 (JSON::ParserError)
|
|
149
146
|
#
|
|
150
147
|
# When set to +true+:
|
|
151
148
|
# # The last value is used.
|
|
152
|
-
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
153
|
-
#
|
|
154
|
-
# When set to +false+, the future default:
|
|
155
|
-
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
149
|
+
# JSON.parse('{"a": 1, "a": 2}', allow_duplicate_key: true) # => {"a" => 2}
|
|
156
150
|
#
|
|
157
151
|
# ---
|
|
158
152
|
#
|
|
@@ -161,15 +155,15 @@ require 'json/common'
|
|
|
161
155
|
# defaults to +false+.
|
|
162
156
|
#
|
|
163
157
|
# With the default, +false+:
|
|
164
|
-
# # Raises JSON::ParserError (
|
|
158
|
+
# # Raises JSON::ParserError (unexpected token 'NaN]' at line 1 column 2):
|
|
165
159
|
# JSON.parse('[NaN]')
|
|
166
|
-
# # Raises JSON::ParserError (
|
|
160
|
+
# # Raises JSON::ParserError (unexpected token 'Infinity]' at line 1 column 2):
|
|
167
161
|
# JSON.parse('[Infinity]')
|
|
168
|
-
# # Raises JSON::ParserError (
|
|
162
|
+
# # Raises JSON::ParserError (invalid number: '-Infinity]' at line 1 column 2):
|
|
169
163
|
# JSON.parse('[-Infinity]')
|
|
170
164
|
# Allow:
|
|
171
165
|
# source = '[NaN, Infinity, -Infinity]'
|
|
172
|
-
# ruby = JSON.parse(source,
|
|
166
|
+
# ruby = JSON.parse(source, allow_nan: true)
|
|
173
167
|
# ruby # => [NaN, Infinity, -Infinity]
|
|
174
168
|
#
|
|
175
169
|
# ---
|
|
@@ -190,13 +184,11 @@ require 'json/common'
|
|
|
190
184
|
# JavaScript style comments (either <tt>// comment</tt> or <tt>/* comment */</tt>);
|
|
191
185
|
# defaults to +false+.
|
|
192
186
|
#
|
|
193
|
-
# When
|
|
187
|
+
# When set to +false+, the default:
|
|
188
|
+
# JSON.parse('/* comment */ {"a": 1, "a": 2}') # unexpected token '/*' at line 1 column 1 (JSON::ParserError)
|
|
194
189
|
#
|
|
195
190
|
# When set to +true+, comments are ignored:
|
|
196
|
-
# JSON.parse('/* comment */ {"a": 1,
|
|
197
|
-
#
|
|
198
|
-
# When set to +false+, the future default:
|
|
199
|
-
# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
|
|
191
|
+
# JSON.parse('/* comment */ {"a": 1} // more comment', allow_comments: true) # => {"a" => 1}
|
|
200
192
|
#
|
|
201
193
|
# ---
|
|
202
194
|
#
|
|
@@ -205,7 +197,7 @@ require 'json/common'
|
|
|
205
197
|
# defaults to +false+.
|
|
206
198
|
#
|
|
207
199
|
# With the default, +false+:
|
|
208
|
-
# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
|
|
200
|
+
# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string: \nWorld" at line 2 column 0 (JSON::ParserError)
|
|
209
201
|
#
|
|
210
202
|
# When enabled:
|
|
211
203
|
# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
|
|
@@ -217,7 +209,7 @@ require 'json/common'
|
|
|
217
209
|
# defaults to +false+.
|
|
218
210
|
#
|
|
219
211
|
# With the default, +false+:
|
|
220
|
-
# JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
|
|
212
|
+
# JSON.parse('"Hell\o"') # invalid escape character in string: '\o"' at line 1 column 6 (JSON::ParserError)
|
|
221
213
|
#
|
|
222
214
|
# When enabled:
|
|
223
215
|
# JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
|
|
@@ -236,8 +228,8 @@ require 'json/common'
|
|
|
236
228
|
# ruby = JSON.parse(source)
|
|
237
229
|
# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
|
|
238
230
|
# Use Symbols:
|
|
239
|
-
# ruby = JSON.parse(source,
|
|
240
|
-
# ruby # => {:
|
|
231
|
+
# ruby = JSON.parse(source, symbolize_names: true)
|
|
232
|
+
# ruby # => {a: "foo", b: 1.0, c: true, d: false, e: nil}
|
|
241
233
|
#
|
|
242
234
|
# ---
|
|
243
235
|
#
|
|
@@ -250,7 +242,7 @@ require 'json/common'
|
|
|
250
242
|
# ruby = JSON.parse(source)
|
|
251
243
|
# ruby.class # => Hash
|
|
252
244
|
# Use class \OpenStruct:
|
|
253
|
-
# ruby = JSON.parse(source,
|
|
245
|
+
# ruby = JSON.parse(source, object_class: OpenStruct)
|
|
254
246
|
# ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
|
|
255
247
|
#
|
|
256
248
|
# ---
|
|
@@ -264,13 +256,8 @@ require 'json/common'
|
|
|
264
256
|
# ruby = JSON.parse(source)
|
|
265
257
|
# ruby.class # => Array
|
|
266
258
|
# Use class \Set:
|
|
267
|
-
# ruby = JSON.parse(source,
|
|
268
|
-
# ruby # =>
|
|
269
|
-
#
|
|
270
|
-
# ---
|
|
271
|
-
#
|
|
272
|
-
# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
|
|
273
|
-
# See {\JSON Additions}[#module-JSON-label-JSON+Additions].
|
|
259
|
+
# ruby = JSON.parse(source, array_class: Set)
|
|
260
|
+
# ruby # => Set["foo", 1.0, true, false, nil]
|
|
274
261
|
#
|
|
275
262
|
# === Generating \JSON
|
|
276
263
|
#
|
|
@@ -332,22 +319,22 @@ require 'json/common'
|
|
|
332
319
|
# a \String containing a \JSON string representation of the source:
|
|
333
320
|
# JSON.generate(:foo) # => '"foo"'
|
|
334
321
|
# JSON.generate(Complex(0, 0)) # => '"0+0i"'
|
|
335
|
-
# JSON.generate(Dir.new('.')) # => '"#<Dir
|
|
322
|
+
# JSON.generate(Dir.new('.')) # => '"#<Dir:0x...>"'
|
|
336
323
|
#
|
|
337
324
|
# ==== Generating Options
|
|
338
325
|
#
|
|
339
326
|
# ====== Input Options
|
|
340
327
|
#
|
|
341
328
|
# Option +allow_nan+ (boolean) specifies whether
|
|
342
|
-
# +NaN+, +Infinity+, and
|
|
329
|
+
# +NaN+, +Infinity+, and +-Infinity+ may be generated;
|
|
343
330
|
# defaults to +false+.
|
|
344
331
|
#
|
|
345
332
|
# With the default, +false+:
|
|
346
|
-
# # Raises JSON::GeneratorError (
|
|
333
|
+
# # Raises JSON::GeneratorError (NaN not allowed in JSON):
|
|
347
334
|
# JSON.generate(JSON::NaN)
|
|
348
|
-
# # Raises JSON::GeneratorError (
|
|
335
|
+
# # Raises JSON::GeneratorError (Infinity not allowed in JSON):
|
|
349
336
|
# JSON.generate(JSON::Infinity)
|
|
350
|
-
# # Raises JSON::GeneratorError (
|
|
337
|
+
# # Raises JSON::GeneratorError (-Infinity not allowed in JSON):
|
|
351
338
|
# JSON.generate(JSON::MinusInfinity)
|
|
352
339
|
#
|
|
353
340
|
# Allow:
|
|
@@ -358,20 +345,15 @@ require 'json/common'
|
|
|
358
345
|
#
|
|
359
346
|
# Option +allow_duplicate_key+ (boolean) specifies whether
|
|
360
347
|
# hashes with duplicate keys should be allowed or produce an error.
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
# With the default, (not set):
|
|
364
|
-
# Warning[:deprecated] = true
|
|
365
|
-
# JSON.generate({ foo: 1, "foo" => 2 })
|
|
366
|
-
# # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
|
|
367
|
-
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
368
|
-
# # => '{"foo":1,"foo":2}'
|
|
348
|
+
# Defaults to +false+, which raises an error.
|
|
369
349
|
#
|
|
370
|
-
# With
|
|
371
|
-
# JSON.generate({
|
|
350
|
+
# With the default, +false+:
|
|
351
|
+
# JSON.generate({foo: 1, "foo" => 2})
|
|
372
352
|
# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
|
|
373
353
|
#
|
|
374
|
-
#
|
|
354
|
+
# With +true+:
|
|
355
|
+
# JSON.generate({foo: 1, "foo" => 2}, allow_duplicate_key: true)
|
|
356
|
+
# # => '{"foo":1,"foo":2}'
|
|
375
357
|
#
|
|
376
358
|
# ---
|
|
377
359
|
#
|
|
@@ -383,17 +365,18 @@ require 'json/common'
|
|
|
383
365
|
# JSON.generate(obj) # => '[[[[[[0]]]]]]'
|
|
384
366
|
#
|
|
385
367
|
# Too deep:
|
|
386
|
-
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
368
|
+
# # Raises JSON::NestingError (nesting of 2 is too deep. Did you try to serialize objects with circular references?):
|
|
387
369
|
# JSON.generate(obj, max_nesting: 2)
|
|
388
370
|
#
|
|
389
371
|
# With +false+:
|
|
390
372
|
# obj = []
|
|
391
373
|
# obj[0] = obj
|
|
392
|
-
# # Raises
|
|
374
|
+
# # Raises SystemStackError (stack level too deep):
|
|
393
375
|
# JSON.generate(obj, max_nesting: false)
|
|
394
376
|
#
|
|
395
|
-
# Setting +max_nesting+ to +false+ can lead to a
|
|
396
|
-
# in an unrecoverable state.
|
|
377
|
+
# Setting +max_nesting+ to +false+ or a very large number can lead to a stack overflow
|
|
378
|
+
# which may leave the process in an unrecoverable state.
|
|
379
|
+
# It is highly discouraged.
|
|
397
380
|
#
|
|
398
381
|
# ====== Escaping Options
|
|
399
382
|
#
|
|
@@ -427,7 +410,7 @@ require 'json/common'
|
|
|
427
410
|
# inserted before the colon in each \JSON object's pair;
|
|
428
411
|
# defaults to the empty \String, <tt>''</tt>.
|
|
429
412
|
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
|
|
430
|
-
# hash are sorted when generating the output; defaults to
|
|
413
|
+
# hash are sorted when generating the output; defaults to +false+.
|
|
431
414
|
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
|
|
432
415
|
# the entire \Hash and must return a \Hash with its pairs in the desired
|
|
433
416
|
# order, allowing for arbitrary sort orders.
|
|
@@ -456,248 +439,13 @@ require 'json/common'
|
|
|
456
439
|
# "foo" : [
|
|
457
440
|
# "bar",
|
|
458
441
|
# "baz"
|
|
459
|
-
#
|
|
442
|
+
# ],
|
|
460
443
|
# "bat" : {
|
|
461
444
|
# "bam" : 0,
|
|
462
445
|
# "bad" : 1
|
|
463
446
|
# }
|
|
464
447
|
# }
|
|
465
448
|
#
|
|
466
|
-
# == \JSON Additions
|
|
467
|
-
#
|
|
468
|
-
# Note that JSON Additions must only be used with trusted data, and is
|
|
469
|
-
# deprecated.
|
|
470
|
-
#
|
|
471
|
-
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|
|
472
|
-
# you have a new \String, instead of the object you began with:
|
|
473
|
-
# ruby0 = Range.new(0, 2)
|
|
474
|
-
# json = JSON.generate(ruby0)
|
|
475
|
-
# json # => '0..2"'
|
|
476
|
-
# ruby1 = JSON.parse(json)
|
|
477
|
-
# ruby1 # => '0..2'
|
|
478
|
-
# ruby1.class # => String
|
|
479
|
-
#
|
|
480
|
-
# You can use \JSON _additions_ to preserve the original object.
|
|
481
|
-
# The addition is an extension of a ruby class, so that:
|
|
482
|
-
# - \JSON.generate stores more information in the \JSON string.
|
|
483
|
-
# - \JSON.parse, called with option +create_additions+,
|
|
484
|
-
# uses that information to create a proper Ruby object.
|
|
485
|
-
#
|
|
486
|
-
# This example shows a \Range being generated into \JSON
|
|
487
|
-
# and parsed back into Ruby, both without and with
|
|
488
|
-
# the addition for \Range:
|
|
489
|
-
# ruby = Range.new(0, 2)
|
|
490
|
-
# # This passage does not use the addition for Range.
|
|
491
|
-
# json0 = JSON.generate(ruby)
|
|
492
|
-
# ruby0 = JSON.parse(json0)
|
|
493
|
-
# # This passage uses the addition for Range.
|
|
494
|
-
# require 'json/add/range'
|
|
495
|
-
# json1 = JSON.generate(ruby)
|
|
496
|
-
# ruby1 = JSON.parse(json1, create_additions: true)
|
|
497
|
-
# # Make a nice display.
|
|
498
|
-
# display = <<~EOT
|
|
499
|
-
# Generated JSON:
|
|
500
|
-
# Without addition: #{json0} (#{json0.class})
|
|
501
|
-
# With addition: #{json1} (#{json1.class})
|
|
502
|
-
# Parsed JSON:
|
|
503
|
-
# Without addition: #{ruby0.inspect} (#{ruby0.class})
|
|
504
|
-
# With addition: #{ruby1.inspect} (#{ruby1.class})
|
|
505
|
-
# EOT
|
|
506
|
-
# puts display
|
|
507
|
-
#
|
|
508
|
-
# This output shows the different results:
|
|
509
|
-
# Generated JSON:
|
|
510
|
-
# Without addition: "0..2" (String)
|
|
511
|
-
# With addition: {"json_class":"Range","a":[0,2,false]} (String)
|
|
512
|
-
# Parsed JSON:
|
|
513
|
-
# Without addition: "0..2" (String)
|
|
514
|
-
# With addition: 0..2 (Range)
|
|
515
|
-
#
|
|
516
|
-
# The \JSON module includes additions for certain classes.
|
|
517
|
-
# You can also craft custom additions.
|
|
518
|
-
# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
|
|
519
|
-
#
|
|
520
|
-
# === Built-in Additions
|
|
521
|
-
#
|
|
522
|
-
# The \JSON module includes additions for certain classes.
|
|
523
|
-
# To use an addition, +require+ its source:
|
|
524
|
-
# - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
|
|
525
|
-
# - Complex: <tt>require 'json/add/complex'</tt>
|
|
526
|
-
# - Date: <tt>require 'json/add/date'</tt>
|
|
527
|
-
# - DateTime: <tt>require 'json/add/date_time'</tt>
|
|
528
|
-
# - Exception: <tt>require 'json/add/exception'</tt>
|
|
529
|
-
# - OpenStruct: <tt>require 'json/add/ostruct'</tt>
|
|
530
|
-
# - Range: <tt>require 'json/add/range'</tt>
|
|
531
|
-
# - Rational: <tt>require 'json/add/rational'</tt>
|
|
532
|
-
# - Regexp: <tt>require 'json/add/regexp'</tt>
|
|
533
|
-
# - Set: <tt>require 'json/add/set'</tt>
|
|
534
|
-
# - Struct: <tt>require 'json/add/struct'</tt>
|
|
535
|
-
# - Symbol: <tt>require 'json/add/symbol'</tt>
|
|
536
|
-
# - Time: <tt>require 'json/add/time'</tt>
|
|
537
|
-
#
|
|
538
|
-
# To reduce punctuation clutter, the examples below
|
|
539
|
-
# show the generated \JSON via +puts+, rather than the usual +inspect+,
|
|
540
|
-
#
|
|
541
|
-
# \BigDecimal:
|
|
542
|
-
# require 'json/add/bigdecimal'
|
|
543
|
-
# ruby0 = BigDecimal(0) # 0.0
|
|
544
|
-
# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
|
|
545
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 0.0
|
|
546
|
-
# ruby1.class # => BigDecimal
|
|
547
|
-
#
|
|
548
|
-
# \Complex:
|
|
549
|
-
# require 'json/add/complex'
|
|
550
|
-
# ruby0 = Complex(1+0i) # 1+0i
|
|
551
|
-
# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
|
|
552
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 1+0i
|
|
553
|
-
# ruby1.class # Complex
|
|
554
|
-
#
|
|
555
|
-
# \Date:
|
|
556
|
-
# require 'json/add/date'
|
|
557
|
-
# ruby0 = Date.today # 2020-05-02
|
|
558
|
-
# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
|
|
559
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
|
|
560
|
-
# ruby1.class # Date
|
|
561
|
-
#
|
|
562
|
-
# \DateTime:
|
|
563
|
-
# require 'json/add/date_time'
|
|
564
|
-
# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
|
|
565
|
-
# 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}
|
|
566
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
|
|
567
|
-
# ruby1.class # DateTime
|
|
568
|
-
#
|
|
569
|
-
# \Exception (and its subclasses including \RuntimeError):
|
|
570
|
-
# require 'json/add/exception'
|
|
571
|
-
# ruby0 = Exception.new('A message') # A message
|
|
572
|
-
# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
|
|
573
|
-
# ruby1 = JSON.parse(json, create_additions: true) # A message
|
|
574
|
-
# ruby1.class # Exception
|
|
575
|
-
# ruby0 = RuntimeError.new('Another message') # Another message
|
|
576
|
-
# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
|
|
577
|
-
# ruby1 = JSON.parse(json, create_additions: true) # Another message
|
|
578
|
-
# ruby1.class # RuntimeError
|
|
579
|
-
#
|
|
580
|
-
# \OpenStruct:
|
|
581
|
-
# require 'json/add/ostruct'
|
|
582
|
-
# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
|
|
583
|
-
# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
|
|
584
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
|
|
585
|
-
# ruby1.class # OpenStruct
|
|
586
|
-
#
|
|
587
|
-
# \Range:
|
|
588
|
-
# require 'json/add/range'
|
|
589
|
-
# ruby0 = Range.new(0, 2) # 0..2
|
|
590
|
-
# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
|
|
591
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 0..2
|
|
592
|
-
# ruby1.class # Range
|
|
593
|
-
#
|
|
594
|
-
# \Rational:
|
|
595
|
-
# require 'json/add/rational'
|
|
596
|
-
# ruby0 = Rational(1, 3) # 1/3
|
|
597
|
-
# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
|
|
598
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 1/3
|
|
599
|
-
# ruby1.class # Rational
|
|
600
|
-
#
|
|
601
|
-
# \Regexp:
|
|
602
|
-
# require 'json/add/regexp'
|
|
603
|
-
# ruby0 = Regexp.new('foo') # (?-mix:foo)
|
|
604
|
-
# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
|
|
605
|
-
# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
|
|
606
|
-
# ruby1.class # Regexp
|
|
607
|
-
#
|
|
608
|
-
# \Set:
|
|
609
|
-
# require 'json/add/set'
|
|
610
|
-
# ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
|
|
611
|
-
# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
|
|
612
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
|
|
613
|
-
# ruby1.class # Set
|
|
614
|
-
#
|
|
615
|
-
# \Struct:
|
|
616
|
-
# require 'json/add/struct'
|
|
617
|
-
# Customer = Struct.new(:name, :address) # Customer
|
|
618
|
-
# ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
|
|
619
|
-
# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
|
|
620
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
|
|
621
|
-
# ruby1.class # Customer
|
|
622
|
-
#
|
|
623
|
-
# \Symbol:
|
|
624
|
-
# require 'json/add/symbol'
|
|
625
|
-
# ruby0 = :foo # foo
|
|
626
|
-
# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
|
|
627
|
-
# ruby1 = JSON.parse(json, create_additions: true) # foo
|
|
628
|
-
# ruby1.class # Symbol
|
|
629
|
-
#
|
|
630
|
-
# \Time:
|
|
631
|
-
# require 'json/add/time'
|
|
632
|
-
# ruby0 = Time.now # 2020-05-02 11:28:26 -0500
|
|
633
|
-
# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
|
|
634
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
|
|
635
|
-
# ruby1.class # Time
|
|
636
|
-
#
|
|
637
|
-
#
|
|
638
|
-
# === Custom \JSON Additions
|
|
639
|
-
#
|
|
640
|
-
# In addition to the \JSON additions provided,
|
|
641
|
-
# you can craft \JSON additions of your own,
|
|
642
|
-
# either for Ruby built-in classes or for user-defined classes.
|
|
643
|
-
#
|
|
644
|
-
# Here's a user-defined class +Foo+:
|
|
645
|
-
# class Foo
|
|
646
|
-
# attr_accessor :bar, :baz
|
|
647
|
-
# def initialize(bar, baz)
|
|
648
|
-
# self.bar = bar
|
|
649
|
-
# self.baz = baz
|
|
650
|
-
# end
|
|
651
|
-
# end
|
|
652
|
-
#
|
|
653
|
-
# Here's the \JSON addition for it:
|
|
654
|
-
# # Extend class Foo with JSON addition.
|
|
655
|
-
# class Foo
|
|
656
|
-
# # Serialize Foo object with its class name and arguments
|
|
657
|
-
# def to_json(*args)
|
|
658
|
-
# {
|
|
659
|
-
# JSON.create_id => self.class.name,
|
|
660
|
-
# 'a' => [ bar, baz ]
|
|
661
|
-
# }.to_json(*args)
|
|
662
|
-
# end
|
|
663
|
-
# # Deserialize JSON string by constructing new Foo object with arguments.
|
|
664
|
-
# def self.json_create(object)
|
|
665
|
-
# new(*object['a'])
|
|
666
|
-
# end
|
|
667
|
-
# end
|
|
668
|
-
#
|
|
669
|
-
# Demonstration:
|
|
670
|
-
# require 'json'
|
|
671
|
-
# # This Foo object has no custom addition.
|
|
672
|
-
# foo0 = Foo.new(0, 1)
|
|
673
|
-
# json0 = JSON.generate(foo0)
|
|
674
|
-
# obj0 = JSON.parse(json0)
|
|
675
|
-
# # Lood the custom addition.
|
|
676
|
-
# require_relative 'foo_addition'
|
|
677
|
-
# # This foo has the custom addition.
|
|
678
|
-
# foo1 = Foo.new(0, 1)
|
|
679
|
-
# json1 = JSON.generate(foo1)
|
|
680
|
-
# obj1 = JSON.parse(json1, create_additions: true)
|
|
681
|
-
# # Make a nice display.
|
|
682
|
-
# display = <<~EOT
|
|
683
|
-
# Generated JSON:
|
|
684
|
-
# Without custom addition: #{json0} (#{json0.class})
|
|
685
|
-
# With custom addition: #{json1} (#{json1.class})
|
|
686
|
-
# Parsed JSON:
|
|
687
|
-
# Without custom addition: #{obj0.inspect} (#{obj0.class})
|
|
688
|
-
# With custom addition: #{obj1.inspect} (#{obj1.class})
|
|
689
|
-
# EOT
|
|
690
|
-
# puts display
|
|
691
|
-
#
|
|
692
|
-
# Output:
|
|
693
|
-
#
|
|
694
|
-
# Generated JSON:
|
|
695
|
-
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
|
696
|
-
# With custom addition: {"json_class":"Foo","a":[0,1]} (String)
|
|
697
|
-
# Parsed JSON:
|
|
698
|
-
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
|
699
|
-
# With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
|
|
700
|
-
#
|
|
701
449
|
module JSON
|
|
702
450
|
require 'json/version'
|
|
703
451
|
require 'json/ext'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -36,25 +36,9 @@ files:
|
|
|
36
36
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
37
37
|
- json.gemspec
|
|
38
38
|
- lib/json.rb
|
|
39
|
-
- lib/json/add/bigdecimal.rb
|
|
40
|
-
- lib/json/add/complex.rb
|
|
41
|
-
- lib/json/add/core.rb
|
|
42
|
-
- lib/json/add/date.rb
|
|
43
|
-
- lib/json/add/date_time.rb
|
|
44
|
-
- lib/json/add/exception.rb
|
|
45
|
-
- lib/json/add/ostruct.rb
|
|
46
|
-
- lib/json/add/range.rb
|
|
47
|
-
- lib/json/add/rational.rb
|
|
48
|
-
- lib/json/add/regexp.rb
|
|
49
|
-
- lib/json/add/set.rb
|
|
50
|
-
- lib/json/add/string.rb
|
|
51
|
-
- lib/json/add/struct.rb
|
|
52
|
-
- lib/json/add/symbol.rb
|
|
53
|
-
- lib/json/add/time.rb
|
|
54
39
|
- lib/json/common.rb
|
|
55
40
|
- lib/json/ext.rb
|
|
56
41
|
- lib/json/ext/generator/state.rb
|
|
57
|
-
- lib/json/generic_object.rb
|
|
58
42
|
- lib/json/truffle_ruby/generator.rb
|
|
59
43
|
- lib/json/version.rb
|
|
60
44
|
homepage: https://github.com/ruby/json
|
data/lib/json/add/bigdecimal.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
|
3
|
-
require 'json'
|
|
4
|
-
end
|
|
5
|
-
begin
|
|
6
|
-
require 'bigdecimal'
|
|
7
|
-
rescue LoadError
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
class BigDecimal
|
|
11
|
-
|
|
12
|
-
# See #as_json.
|
|
13
|
-
def self.json_create(object)
|
|
14
|
-
BigDecimal._load object['b']
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be used
|
|
18
|
-
# to serialize and deserialize a \BigDecimal object;
|
|
19
|
-
# see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
|
|
20
|
-
#
|
|
21
|
-
# \Method <tt>BigDecimal#as_json</tt> serializes +self+,
|
|
22
|
-
# returning a 2-element hash representing +self+:
|
|
23
|
-
#
|
|
24
|
-
# require 'json/add/bigdecimal'
|
|
25
|
-
# x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
|
|
26
|
-
# y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"}
|
|
27
|
-
# z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
|
|
28
|
-
#
|
|
29
|
-
# \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object:
|
|
30
|
-
#
|
|
31
|
-
# BigDecimal.json_create(x) # => 0.2e1
|
|
32
|
-
# BigDecimal.json_create(y) # => 0.2e1
|
|
33
|
-
# BigDecimal.json_create(z) # => 0.2e1
|
|
34
|
-
#
|
|
35
|
-
def as_json(*)
|
|
36
|
-
{
|
|
37
|
-
JSON.create_id => self.class.name,
|
|
38
|
-
'b' => _dump.force_encoding(Encoding::UTF_8),
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Returns a JSON string representing +self+:
|
|
43
|
-
#
|
|
44
|
-
# require 'json/add/bigdecimal'
|
|
45
|
-
# puts BigDecimal(2).to_json
|
|
46
|
-
# puts BigDecimal(2.0, 4).to_json
|
|
47
|
-
# puts BigDecimal(Complex(2, 0)).to_json
|
|
48
|
-
#
|
|
49
|
-
# Output:
|
|
50
|
-
#
|
|
51
|
-
# {"json_class":"BigDecimal","b":"27:0.2e1"}
|
|
52
|
-
# {"json_class":"BigDecimal","b":"36:0.2e1"}
|
|
53
|
-
# {"json_class":"BigDecimal","b":"27:0.2e1"}
|
|
54
|
-
#
|
|
55
|
-
def to_json(*args)
|
|
56
|
-
as_json.to_json(*args)
|
|
57
|
-
end
|
|
58
|
-
end if defined?(::BigDecimal)
|
data/lib/json/add/complex.rb
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
|
3
|
-
require 'json'
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
class Complex
|
|
7
|
-
|
|
8
|
-
# See #as_json.
|
|
9
|
-
def self.json_create(object)
|
|
10
|
-
Complex(object['r'], object['i'])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used
|
|
14
|
-
# to serialize and deserialize a \Complex object;
|
|
15
|
-
# see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
|
|
16
|
-
#
|
|
17
|
-
# \Method <tt>Complex#as_json</tt> serializes +self+,
|
|
18
|
-
# returning a 2-element hash representing +self+:
|
|
19
|
-
#
|
|
20
|
-
# require 'json/add/complex'
|
|
21
|
-
# x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0}
|
|
22
|
-
# y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}
|
|
23
|
-
#
|
|
24
|
-
# \Method +JSON.create+ deserializes such a hash, returning a \Complex object:
|
|
25
|
-
#
|
|
26
|
-
# Complex.json_create(x) # => (2+0i)
|
|
27
|
-
# Complex.json_create(y) # => (2.0+4i)
|
|
28
|
-
#
|
|
29
|
-
def as_json(*)
|
|
30
|
-
{
|
|
31
|
-
JSON.create_id => self.class.name,
|
|
32
|
-
'r' => real,
|
|
33
|
-
'i' => imag,
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Returns a JSON string representing +self+:
|
|
38
|
-
#
|
|
39
|
-
# require 'json/add/complex'
|
|
40
|
-
# puts Complex(2).to_json
|
|
41
|
-
# puts Complex(2.0, 4).to_json
|
|
42
|
-
#
|
|
43
|
-
# Output:
|
|
44
|
-
#
|
|
45
|
-
# {"json_class":"Complex","r":2,"i":0}
|
|
46
|
-
# {"json_class":"Complex","r":2.0,"i":4}
|
|
47
|
-
#
|
|
48
|
-
def to_json(*args)
|
|
49
|
-
as_json.to_json(*args)
|
|
50
|
-
end
|
|
51
|
-
end
|
data/lib/json/add/core.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
# This file requires the implementations of ruby core's custom objects for
|
|
3
|
-
# serialisation/deserialisation.
|
|
4
|
-
|
|
5
|
-
require 'json/add/date'
|
|
6
|
-
require 'json/add/date_time'
|
|
7
|
-
require 'json/add/exception'
|
|
8
|
-
require 'json/add/range'
|
|
9
|
-
require 'json/add/regexp'
|
|
10
|
-
require 'json/add/string'
|
|
11
|
-
require 'json/add/struct'
|
|
12
|
-
require 'json/add/symbol'
|
|
13
|
-
require 'json/add/time'
|