json_pure 2.2.0 → 2.5.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +51 -0
  3. data/LICENSE +56 -0
  4. data/README.md +17 -1
  5. data/VERSION +1 -1
  6. data/json_pure.gemspec +49 -26
  7. data/lib/json.rb +549 -29
  8. data/lib/json/add/bigdecimal.rb +2 -2
  9. data/lib/json/add/complex.rb +2 -3
  10. data/lib/json/add/rational.rb +2 -3
  11. data/lib/json/add/regexp.rb +2 -2
  12. data/lib/json/common.rb +370 -125
  13. data/lib/json/pure/generator.rb +31 -10
  14. data/lib/json/pure/parser.rb +31 -5
  15. data/lib/json/version.rb +1 -1
  16. data/tests/fixtures/fail29.json +1 -0
  17. data/tests/fixtures/fail30.json +1 -0
  18. data/tests/fixtures/fail31.json +1 -0
  19. data/tests/fixtures/fail32.json +1 -0
  20. data/tests/json_addition_test.rb +0 -4
  21. data/tests/json_common_interface_test.rb +47 -4
  22. data/tests/json_fixtures_test.rb +9 -1
  23. data/tests/json_generator_test.rb +30 -8
  24. data/tests/json_parser_test.rb +39 -14
  25. data/tests/lib/core_assertions.rb +763 -0
  26. data/tests/lib/envutil.rb +365 -0
  27. data/tests/lib/find_executable.rb +22 -0
  28. data/tests/lib/helper.rb +4 -0
  29. data/tests/ractor_test.rb +30 -0
  30. data/tests/test_helper.rb +3 -3
  31. metadata +28 -48
  32. data/.gitignore +0 -17
  33. data/.travis.yml +0 -23
  34. data/README-json-jruby.md +0 -33
  35. data/Rakefile +0 -408
  36. data/diagrams/.keep +0 -0
  37. data/ext/json/ext/fbuffer/fbuffer.h +0 -187
  38. data/ext/json/ext/generator/depend +0 -1
  39. data/ext/json/ext/generator/extconf.rb +0 -4
  40. data/ext/json/ext/generator/generator.c +0 -1444
  41. data/ext/json/ext/generator/generator.h +0 -171
  42. data/ext/json/ext/parser/depend +0 -1
  43. data/ext/json/ext/parser/extconf.rb +0 -6
  44. data/ext/json/ext/parser/parser.c +0 -2131
  45. data/ext/json/ext/parser/parser.h +0 -91
  46. data/ext/json/ext/parser/parser.rl +0 -891
  47. data/ext/json/extconf.rb +0 -2
  48. data/install.rb +0 -23
  49. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  50. data/java/src/json/ext/Generator.java +0 -443
  51. data/java/src/json/ext/GeneratorMethods.java +0 -231
  52. data/java/src/json/ext/GeneratorService.java +0 -42
  53. data/java/src/json/ext/GeneratorState.java +0 -490
  54. data/java/src/json/ext/OptionsReader.java +0 -113
  55. data/java/src/json/ext/Parser.java +0 -2362
  56. data/java/src/json/ext/Parser.rl +0 -893
  57. data/java/src/json/ext/ParserService.java +0 -34
  58. data/java/src/json/ext/RuntimeInfo.java +0 -116
  59. data/java/src/json/ext/StringDecoder.java +0 -166
  60. data/java/src/json/ext/StringEncoder.java +0 -111
  61. data/java/src/json/ext/Utils.java +0 -88
  62. data/json-java.gemspec +0 -38
  63. data/json.gemspec +0 -0
  64. data/references/rfc7159.txt +0 -899
  65. data/tools/diff.sh +0 -18
  66. data/tools/fuzz.rb +0 -131
  67. data/tools/server.rb +0 -62
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08028c4e7729dcf45631d4654799aa31280e1fb172ae74ff05a5c5fa85cbefc8'
4
- data.tar.gz: 5845322c2daa41d815c4b845c6561d2addf86b459a5c093590317210d6d85901
3
+ metadata.gz: d55675fae6550131acdd6d82e4c1f307caf7dfd7654b42e2c4eb44f0c89fad79
4
+ data.tar.gz: e715e4be760237f640f151b4ab3e48bdf8521e3a5c9a4155feaa06b9a6f441b3
5
5
  SHA512:
6
- metadata.gz: 5ff74c77b754fd54e11516c7986f975c262c385d6dc4b00a6db23b942c241a3bb546c77cb20abf23ab2ee4ab8aca53a74584ebfe279a3972ada969c0388e3ab0
7
- data.tar.gz: e74601af87a7ec32952fd596b4981b0d26c4f96ddb88979a26b2fb06604dff204d38ba7c120cd0389756edb83cbd81b6fc569d16f5f7740b8b2915d63cdc8f22
6
+ metadata.gz: 3cbc869733b4409e9921a45fccc8f03e4b92e646feb19440d04908aaa9639349c3350b63d733361cd0508404b589c1e3a79c18da6095b20a6ed368ec73440e63
7
+ data.tar.gz: cf240eeac4109b3bdb13d9ed5c0d725267ba806ac6794f81bdfb24c4d89877655a8c34b72867dc70fdda1b9a912ec87dac688bfa888c185f63ff18625a2d61f4
data/CHANGES.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # Changes
2
2
 
3
+ ## 2020-12-22 (2.5.0)
4
+
5
+ * Ready to Ractor-safe at Ruby 3.0.
6
+
7
+ ## 2020-12-17 (2.4.1)
8
+
9
+ * Restore version.rb with 2.4.1
10
+
11
+ ## 2020-12-15 (2.4.0)
12
+
13
+ * Implement a freeze: parser option #447
14
+ * Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations #449
15
+ * Fix JSON.load_file doc #448
16
+ * Fix pure parser with unclosed arrays / objects #425
17
+ * bundle the LICENSE file in the gem #444
18
+ * Add an option to escape forward slash character #405
19
+ * RDoc for JSON #439 #446 #442 #434 #433 #430
20
+
21
+ ## 2020-06-30 (2.3.1)
22
+
23
+ * Spelling and grammar fixes for comments. Pull request #191 by Josh
24
+ Kline.
25
+ * Enhance generic JSON and #generate docs. Pull request #347 by Victor
26
+ Shepelev.
27
+ * Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev.
28
+ * Baseline changes to help (JRuby) development. Pull request #371 by Karol
29
+ Bucek.
30
+ * Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI.
31
+ * Remove invalid JSON.generate description from JSON module rdoc. Pull
32
+ request #384 by Jeremy Evans.
33
+ * Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze.
34
+ * Rdoc enhancements. Pull request #413 by Burdette Lamar.
35
+ * Fixtures/ are not being tested... Pull request #416 by Marc-André
36
+ Lafortune.
37
+ * Use frozen string for hash key. Pull request #420 by Marc-André
38
+ Lafortune.
39
+ * Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette
40
+ Lamar.
41
+ * Small typo fix. Pull request #423 by Marc-André Lafortune.
42
+
43
+ ## 2019-12-11 (2.3.0)
44
+ * Fix default of `create_additions` to always be `false` for `JSON(user_input)`
45
+ and `JSON.parse(user_input, nil)`.
46
+ Note that `JSON.load` remains with default `true` and is meant for internal
47
+ serialization of trusted data. [CVE-2020-10663]
48
+ * Fix passing args all #to_json in json/add/*.
49
+ * Fix encoding issues
50
+ * Fix issues of keyword vs positional parameter
51
+ * Fix JSON::Parser against bigdecimal updates
52
+ * Bug fixes to JRuby port
53
+
3
54
  ## 2019-02-21 (2.2.0)
4
55
  * Adds support for 2.6 BigDecimal and ruby standard library Set datetype.
5
56
 
data/LICENSE ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/README.md CHANGED
@@ -390,6 +390,22 @@ Here are the median comparisons for completeness' sake:
390
390
  secs/call
391
391
  ```
392
392
 
393
+ ## Development
394
+
395
+ ### Release
396
+
397
+ Update the json.gemspec and json-java.gemspec.
398
+
399
+ ```
400
+ rbenv shell 2.6.5
401
+ rake build
402
+ gem push pkg/json-2.3.0.gem
403
+
404
+ rbenv shell jruby-9.2.9.0
405
+ rake build
406
+ gem push pkg/json-2.3.0-java.gem
407
+ ```
408
+
393
409
  ## Author
394
410
 
395
411
  Florian Frank <mailto:flori@ping.de>
@@ -406,4 +422,4 @@ The latest version of this library can be downloaded at
406
422
 
407
423
  Online Documentation should be located at
408
424
 
409
- * http://json.rubyforge.org
425
+ * https://www.rubydoc.info/gems/json
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.5.0
@@ -1,38 +1,61 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: json_pure 2.2.0 ruby lib
3
2
 
4
3
  Gem::Specification.new do |s|
5
4
  s.name = "json_pure".freeze
6
- s.version = "2.2.0"
5
+ s.version = File.read("VERSION").chomp
7
6
 
8
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
- s.require_paths = ["lib".freeze]
10
- s.authors = ["Florian Frank".freeze]
11
- s.date = "2019-02-21"
7
+ s.summary = "JSON Implementation for Ruby".freeze
12
8
  s.description = "This is a JSON implementation in pure Ruby.".freeze
9
+ s.licenses = ["Ruby".freeze]
10
+ s.authors = ["Florian Frank".freeze]
13
11
  s.email = "flori@ping.de".freeze
12
+
14
13
  s.extra_rdoc_files = ["README.md".freeze]
15
- s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/set.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze]
16
- s.homepage = "http://flori.github.com/json".freeze
17
- s.licenses = ["Ruby".freeze]
18
14
  s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze]
19
- s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze)
20
- s.rubygems_version = "2.7.6".freeze
21
- s.summary = "JSON Implementation for Ruby".freeze
22
- s.test_files = ["./tests/test_helper.rb".freeze]
15
+ s.files = [
16
+ "CHANGES.md".freeze,
17
+ "Gemfile".freeze,
18
+ "LICENSE".freeze,
19
+ "README.md".freeze,
20
+ "VERSION".freeze,
21
+ "json_pure.gemspec".freeze,
22
+ "lib/json.rb".freeze,
23
+ "lib/json/add/bigdecimal.rb".freeze,
24
+ "lib/json/add/complex.rb".freeze,
25
+ "lib/json/add/core.rb".freeze,
26
+ "lib/json/add/date.rb".freeze,
27
+ "lib/json/add/date_time.rb".freeze,
28
+ "lib/json/add/exception.rb".freeze,
29
+ "lib/json/add/ostruct.rb".freeze,
30
+ "lib/json/add/range.rb".freeze,
31
+ "lib/json/add/rational.rb".freeze,
32
+ "lib/json/add/regexp.rb".freeze,
33
+ "lib/json/add/set.rb".freeze,
34
+ "lib/json/add/struct.rb".freeze,
35
+ "lib/json/add/symbol.rb".freeze,
36
+ "lib/json/add/time.rb".freeze,
37
+ "lib/json/common.rb".freeze,
38
+ "lib/json/ext.rb".freeze,
39
+ "lib/json/ext/.keep".freeze,
40
+ "lib/json/generic_object.rb".freeze,
41
+ "lib/json/pure.rb".freeze,
42
+ "lib/json/pure/generator.rb".freeze,
43
+ "lib/json/pure/parser.rb".freeze,
44
+ "lib/json/version.rb".freeze,
45
+ ] + Dir["tests/**/*"]
46
+ s.homepage = "http://flori.github.com/json".freeze
47
+ s.metadata = {
48
+ 'bug_tracker_uri' => 'https://github.com/flori/json/issues',
49
+ 'changelog_uri' => 'https://github.com/flori/json/blob/master/CHANGES.md',
50
+ 'documentation_uri' => 'http://flori.github.io/json/doc/index.html',
51
+ 'homepage_uri' => 'http://flori.github.io/json/',
52
+ 'source_code_uri' => 'https://github.com/flori/json',
53
+ 'wiki_uri' => 'https://github.com/flori/json/wiki'
54
+ }
23
55
 
24
- if s.respond_to? :specification_version then
25
- s.specification_version = 4
56
+ s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
57
+ s.test_files = ["./tests/test_helper.rb".freeze]
26
58
 
27
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
- s.add_development_dependency(%q<rake>.freeze, [">= 0"])
29
- s.add_development_dependency(%q<test-unit>.freeze, ["~> 2.0"])
30
- else
31
- s.add_dependency(%q<rake>.freeze, [">= 0"])
32
- s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
33
- end
34
- else
35
- s.add_dependency(%q<rake>.freeze, [">= 0"])
36
- s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
37
- end
59
+ s.add_development_dependency "rake"
60
+ s.add_development_dependency "test-unit"
38
61
  end
@@ -2,55 +2,575 @@
2
2
  require 'json/common'
3
3
 
4
4
  ##
5
- # = JavaScript Object Notation (JSON)
5
+ # = JavaScript \Object Notation (\JSON)
6
6
  #
7
- # JSON is a lightweight data-interchange format. It is easy for us
8
- # humans to read and write. Plus, equally simple for machines to generate or parse.
9
- # JSON is completely language agnostic, making it the ideal interchange format.
7
+ # \JSON is a lightweight data-interchange format.
10
8
  #
11
- # Built on two universally available structures:
12
- # 1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array.
13
- # 2. An ordered list of values. More commonly called an _array_, vector, sequence or list.
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]
14
16
  #
15
- # To read more about JSON visit: http://json.org
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}
16
21
  #
17
- # == Parsing JSON
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]]
18
26
  #
19
- # To parse a JSON string received by another application or generated within
20
- # your existing application:
27
+ # == Using \Module \JSON
21
28
  #
29
+ # To make module \JSON available in your code, begin with:
22
30
  # require 'json'
23
31
  #
24
- # my_hash = JSON.parse('{"hello": "goodbye"}')
25
- # puts my_hash["hello"] => "goodbye"
32
+ # All examples here assume that this has been done.
26
33
  #
27
- # Notice the extra quotes <tt>''</tt> around the hash notation. Ruby expects
28
- # the argument to be a string and can't convert objects like a hash or array.
34
+ # === Parsing \JSON
29
35
  #
30
- # Ruby converts your string into a hash
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>
31
40
  #
32
- # == Generating JSON
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.
33
45
  #
34
- # Creating a JSON string for communication or serialization is
35
- # just as simple.
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.
36
51
  #
37
- # require 'json'
52
+ # ==== Parsing \JSON Arrays
38
53
  #
39
- # my_hash = {:hello => "goodbye"}
40
- # puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
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
41
59
  #
42
- # Or an alternative way:
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]]
43
64
  #
44
- # require 'json'
45
- # puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"
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
46
258
  #
47
- # <tt>JSON.generate</tt> only allows objects or arrays to be converted
48
- # to JSON syntax. <tt>to_json</tt>, however, accepts many Ruby classes
49
- # even though it acts only as a method for serialization:
259
+ # Option +allow_nan+ (boolean) specifies whether
260
+ # +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
261
+ # defaults to +false+.
50
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
+ # ====== Output Options
289
+ #
290
+ # The default formatting options generate the most compact
291
+ # \JSON data, all on one line and with no whitespace.
292
+ #
293
+ # You can use these formatting options to generate
294
+ # \JSON data in a more open format, using whitespace.
295
+ # See also JSON.pretty_generate.
296
+ #
297
+ # - Option +array_nl+ (\String) specifies a string (usually a newline)
298
+ # to be inserted after each \JSON array; defaults to the empty \String, <tt>''</tt>.
299
+ # - Option +object_nl+ (\String) specifies a string (usually a newline)
300
+ # to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
301
+ # - Option +indent+ (\String) specifies the string (usually spaces) to be
302
+ # used for indentation; defaults to the empty \String, <tt>''</tt>;
303
+ # defaults to the empty \String, <tt>''</tt>;
304
+ # has no effect unless options +array_nl+ or +object_nl+ specify newlines.
305
+ # - Option +space+ (\String) specifies a string (usually a space) to be
306
+ # inserted after the colon in each \JSON object's pair;
307
+ # defaults to the empty \String, <tt>''</tt>.
308
+ # - Option +space_before+ (\String) specifies a string (usually a space) to be
309
+ # inserted before the colon in each \JSON object's pair;
310
+ # defaults to the empty \String, <tt>''</tt>.
311
+ #
312
+ # In this example, +obj+ is used first to generate the shortest
313
+ # \JSON data (no whitespace), then again with all formatting options
314
+ # specified:
315
+ #
316
+ # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
317
+ # json = JSON.generate(obj)
318
+ # puts 'Compact:', json
319
+ # opts = {
320
+ # array_nl: "\n",
321
+ # object_nl: "\n",
322
+ # indent: ' ',
323
+ # space_before: ' ',
324
+ # space: ' '
325
+ # }
326
+ # puts 'Open:', JSON.generate(obj, opts)
327
+ #
328
+ # Output:
329
+ # Compact:
330
+ # {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
331
+ # Open:
332
+ # {
333
+ # "foo" : [
334
+ # "bar",
335
+ # "baz"
336
+ # ],
337
+ # "bat" : {
338
+ # "bam" : 0,
339
+ # "bad" : 1
340
+ # }
341
+ # }
342
+ #
343
+ # == \JSON Additions
344
+ #
345
+ # When you "round trip" a non-\String object from Ruby to \JSON and back,
346
+ # you have a new \String, instead of the object you began with:
347
+ # ruby0 = Range.new(0, 2)
348
+ # json = JSON.generate(ruby0)
349
+ # json # => '0..2"'
350
+ # ruby1 = JSON.parse(json)
351
+ # ruby1 # => '0..2'
352
+ # ruby1.class # => String
353
+ #
354
+ # You can use \JSON _additions_ to preserve the original object.
355
+ # The addition is an extension of a ruby class, so that:
356
+ # - \JSON.generate stores more information in the \JSON string.
357
+ # - \JSON.parse, called with option +create_additions+,
358
+ # uses that information to create a proper Ruby object.
359
+ #
360
+ # This example shows a \Range being generated into \JSON
361
+ # and parsed back into Ruby, both without and with
362
+ # the addition for \Range:
363
+ # ruby = Range.new(0, 2)
364
+ # # This passage does not use the addition for Range.
365
+ # json0 = JSON.generate(ruby)
366
+ # ruby0 = JSON.parse(json0)
367
+ # # This passage uses the addition for Range.
368
+ # require 'json/add/range'
369
+ # json1 = JSON.generate(ruby)
370
+ # ruby1 = JSON.parse(json1, create_additions: true)
371
+ # # Make a nice display.
372
+ # display = <<EOT
373
+ # Generated JSON:
374
+ # Without addition: #{json0} (#{json0.class})
375
+ # With addition: #{json1} (#{json1.class})
376
+ # Parsed JSON:
377
+ # Without addition: #{ruby0.inspect} (#{ruby0.class})
378
+ # With addition: #{ruby1.inspect} (#{ruby1.class})
379
+ # EOT
380
+ # puts display
381
+ #
382
+ # This output shows the different results:
383
+ # Generated JSON:
384
+ # Without addition: "0..2" (String)
385
+ # With addition: {"json_class":"Range","a":[0,2,false]} (String)
386
+ # Parsed JSON:
387
+ # Without addition: "0..2" (String)
388
+ # With addition: 0..2 (Range)
389
+ #
390
+ # The \JSON module includes additions for certain classes.
391
+ # You can also craft custom additions.
392
+ # See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
393
+ #
394
+ # === Built-in Additions
395
+ #
396
+ # The \JSON module includes additions for certain classes.
397
+ # To use an addition, +require+ its source:
398
+ # - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
399
+ # - Complex: <tt>require 'json/add/complex'</tt>
400
+ # - Date: <tt>require 'json/add/date'</tt>
401
+ # - DateTime: <tt>require 'json/add/date_time'</tt>
402
+ # - Exception: <tt>require 'json/add/exception'</tt>
403
+ # - OpenStruct: <tt>require 'json/add/ostruct'</tt>
404
+ # - Range: <tt>require 'json/add/range'</tt>
405
+ # - Rational: <tt>require 'json/add/rational'</tt>
406
+ # - Regexp: <tt>require 'json/add/regexp'</tt>
407
+ # - Set: <tt>require 'json/add/set'</tt>
408
+ # - Struct: <tt>require 'json/add/struct'</tt>
409
+ # - Symbol: <tt>require 'json/add/symbol'</tt>
410
+ # - Time: <tt>require 'json/add/time'</tt>
411
+ #
412
+ # To reduce punctuation clutter, the examples below
413
+ # show the generated \JSON via +puts+, rather than the usual +inspect+,
414
+ #
415
+ # \BigDecimal:
416
+ # require 'json/add/bigdecimal'
417
+ # ruby0 = BigDecimal(0) # 0.0
418
+ # json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
419
+ # ruby1 = JSON.parse(json, create_additions: true) # 0.0
420
+ # ruby1.class # => BigDecimal
421
+ #
422
+ # \Complex:
423
+ # require 'json/add/complex'
424
+ # ruby0 = Complex(1+0i) # 1+0i
425
+ # json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
426
+ # ruby1 = JSON.parse(json, create_additions: true) # 1+0i
427
+ # ruby1.class # Complex
428
+ #
429
+ # \Date:
430
+ # require 'json/add/date'
431
+ # ruby0 = Date.today # 2020-05-02
432
+ # json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
433
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
434
+ # ruby1.class # Date
435
+ #
436
+ # \DateTime:
437
+ # require 'json/add/date_time'
438
+ # ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
439
+ # 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}
440
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
441
+ # ruby1.class # DateTime
442
+ #
443
+ # \Exception (and its subclasses including \RuntimeError):
444
+ # require 'json/add/exception'
445
+ # ruby0 = Exception.new('A message') # A message
446
+ # json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
447
+ # ruby1 = JSON.parse(json, create_additions: true) # A message
448
+ # ruby1.class # Exception
449
+ # ruby0 = RuntimeError.new('Another message') # Another message
450
+ # json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
451
+ # ruby1 = JSON.parse(json, create_additions: true) # Another message
452
+ # ruby1.class # RuntimeError
453
+ #
454
+ # \OpenStruct:
455
+ # require 'json/add/ostruct'
456
+ # ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
457
+ # json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
458
+ # ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
459
+ # ruby1.class # OpenStruct
460
+ #
461
+ # \Range:
462
+ # require 'json/add/range'
463
+ # ruby0 = Range.new(0, 2) # 0..2
464
+ # json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
465
+ # ruby1 = JSON.parse(json, create_additions: true) # 0..2
466
+ # ruby1.class # Range
467
+ #
468
+ # \Rational:
469
+ # require 'json/add/rational'
470
+ # ruby0 = Rational(1, 3) # 1/3
471
+ # json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
472
+ # ruby1 = JSON.parse(json, create_additions: true) # 1/3
473
+ # ruby1.class # Rational
474
+ #
475
+ # \Regexp:
476
+ # require 'json/add/regexp'
477
+ # ruby0 = Regexp.new('foo') # (?-mix:foo)
478
+ # json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
479
+ # ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
480
+ # ruby1.class # Regexp
481
+ #
482
+ # \Set:
483
+ # require 'json/add/set'
484
+ # ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
485
+ # json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
486
+ # ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
487
+ # ruby1.class # Set
488
+ #
489
+ # \Struct:
490
+ # require 'json/add/struct'
491
+ # Customer = Struct.new(:name, :address) # Customer
492
+ # ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
493
+ # json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
494
+ # ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
495
+ # ruby1.class # Customer
496
+ #
497
+ # \Symbol:
498
+ # require 'json/add/symbol'
499
+ # ruby0 = :foo # foo
500
+ # json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
501
+ # ruby1 = JSON.parse(json, create_additions: true) # foo
502
+ # ruby1.class # Symbol
503
+ #
504
+ # \Time:
505
+ # require 'json/add/time'
506
+ # ruby0 = Time.now # 2020-05-02 11:28:26 -0500
507
+ # json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
508
+ # ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
509
+ # ruby1.class # Time
510
+ #
511
+ #
512
+ # === Custom \JSON Additions
513
+ #
514
+ # In addition to the \JSON additions provided,
515
+ # you can craft \JSON additions of your own,
516
+ # either for Ruby built-in classes or for user-defined classes.
517
+ #
518
+ # Here's a user-defined class +Foo+:
519
+ # class Foo
520
+ # attr_accessor :bar, :baz
521
+ # def initialize(bar, baz)
522
+ # self.bar = bar
523
+ # self.baz = baz
524
+ # end
525
+ # end
526
+ #
527
+ # Here's the \JSON addition for it:
528
+ # # Extend class Foo with JSON addition.
529
+ # class Foo
530
+ # # Serialize Foo object with its class name and arguments
531
+ # def to_json(*args)
532
+ # {
533
+ # JSON.create_id => self.class.name,
534
+ # 'a' => [ bar, baz ]
535
+ # }.to_json(*args)
536
+ # end
537
+ # # Deserialize JSON string by constructing new Foo object with arguments.
538
+ # def self.json_create(object)
539
+ # new(*object['a'])
540
+ # end
541
+ # end
542
+ #
543
+ # Demonstration:
51
544
  # require 'json'
545
+ # # This Foo object has no custom addition.
546
+ # foo0 = Foo.new(0, 1)
547
+ # json0 = JSON.generate(foo0)
548
+ # obj0 = JSON.parse(json0)
549
+ # # Lood the custom addition.
550
+ # require_relative 'foo_addition'
551
+ # # This foo has the custom addition.
552
+ # foo1 = Foo.new(0, 1)
553
+ # json1 = JSON.generate(foo1)
554
+ # obj1 = JSON.parse(json1, create_additions: true)
555
+ # # Make a nice display.
556
+ # display = <<EOT
557
+ # Generated JSON:
558
+ # Without custom addition: #{json0} (#{json0.class})
559
+ # With custom addition: #{json1} (#{json1.class})
560
+ # Parsed JSON:
561
+ # Without custom addition: #{obj0.inspect} (#{obj0.class})
562
+ # With custom addition: #{obj1.inspect} (#{obj1.class})
563
+ # EOT
564
+ # puts display
565
+ #
566
+ # Output:
52
567
  #
53
- # 1.to_json => "1"
568
+ # Generated JSON:
569
+ # Without custom addition: "#<Foo:0x0000000006534e80>" (String)
570
+ # With custom addition: {"json_class":"Foo","a":[0,1]} (String)
571
+ # Parsed JSON:
572
+ # Without custom addition: "#<Foo:0x0000000006534e80>" (String)
573
+ # With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
54
574
  #
55
575
  module JSON
56
576
  require 'json/version'