json 2.12.2 → 2.16.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.
data/json.gemspec CHANGED
@@ -44,15 +44,14 @@ spec = Gem::Specification.new do |s|
44
44
  "LEGAL",
45
45
  "README.md",
46
46
  "json.gemspec",
47
- *Dir["lib/**/*.rb"],
48
- ]
47
+ ] + Dir.glob("lib/**/*.rb", base: File.expand_path("..", __FILE__))
49
48
 
50
49
  if java_ext
51
50
  s.platform = 'java'
52
51
  s.files += Dir["lib/json/ext/**/*.jar"]
53
52
  else
54
53
  s.extensions = Dir["ext/json/**/extconf.rb"]
55
- s.files += Dir["ext/json/**/*.{c,h}"]
54
+ s.files += Dir["ext/json/**/*.{c,h,rb}"]
56
55
  end
57
56
  end
58
57
 
data/lib/json/add/core.rb CHANGED
@@ -7,6 +7,7 @@ require 'json/add/date_time'
7
7
  require 'json/add/exception'
8
8
  require 'json/add/range'
9
9
  require 'json/add/regexp'
10
+ require 'json/add/string'
10
11
  require 'json/add/struct'
11
12
  require 'json/add/symbol'
12
13
  require 'json/add/time'
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
3
+ require 'json'
4
+ end
5
+
6
+ class String
7
+ # call-seq: json_create(o)
8
+ #
9
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
10
+ # key "raw"). The Ruby String can be created by this class method.
11
+ def self.json_create(object)
12
+ object["raw"].pack("C*")
13
+ end
14
+
15
+ # call-seq: to_json_raw_object()
16
+ #
17
+ # This method creates a raw object hash, that can be nested into
18
+ # other data structures and will be generated as a raw string. This
19
+ # method should be used, if you want to convert raw strings to JSON
20
+ # instead of UTF-8 strings, e. g. binary data.
21
+ def to_json_raw_object
22
+ {
23
+ JSON.create_id => self.class.name,
24
+ "raw" => unpack("C*"),
25
+ }
26
+ end
27
+
28
+ # call-seq: to_json_raw(*args)
29
+ #
30
+ # This method creates a JSON text from the result of a call to
31
+ # to_json_raw_object of this String.
32
+ def to_json_raw(...)
33
+ to_json_raw_object.to_json(...)
34
+ end
35
+ end
data/lib/json/common.rb CHANGED
@@ -48,7 +48,7 @@ module JSON
48
48
  end
49
49
  end
50
50
 
51
- # TODO: exctract :create_additions support to another gem for version 3.0
51
+ # TODO: extract :create_additions support to another gem for version 3.0
52
52
  def create_additions_proc(opts)
53
53
  if opts[:symbolize_names]
54
54
  raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction"
@@ -71,9 +71,14 @@ module JSON
71
71
  end
72
72
  when object_class
73
73
  if opts[:create_additions] != false
74
- if class_name = object[JSON.create_id]
75
- klass = JSON.deep_const_get(class_name)
76
- if (klass.respond_to?(:json_creatable?) && klass.json_creatable?) || klass.respond_to?(:json_create)
74
+ if class_path = object[JSON.create_id]
75
+ klass = begin
76
+ Object.const_get(class_path)
77
+ rescue NameError => e
78
+ raise ArgumentError, "can't get const #{class_path}: #{e}"
79
+ end
80
+
81
+ if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
77
82
  create_additions_warning if create_additions.nil?
78
83
  object = klass.json_create(object)
79
84
  end
@@ -87,31 +92,32 @@ module JSON
87
92
  opts
88
93
  end
89
94
 
90
- GEM_ROOT = File.expand_path("../../../", __FILE__) + "/"
91
95
  def create_additions_warning
92
- message = "JSON.load implicit support for `create_additions: true` is deprecated " \
96
+ JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \
93
97
  "and will be removed in 3.0, use JSON.unsafe_load or explicitly " \
94
98
  "pass `create_additions: true`"
99
+ end
100
+ end
101
+ end
95
102
 
96
- uplevel = 4
97
- caller_locations(uplevel, 10).each do |frame|
98
- if frame.path.nil? || frame.path.start_with?(GEM_ROOT) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
99
- uplevel += 1
100
- else
101
- break
102
- end
103
- end
104
-
105
- if RUBY_VERSION >= "3.0"
106
- warn(message, uplevel: uplevel - 1, category: :deprecated)
103
+ class << self
104
+ def deprecation_warning(message, uplevel = 3) # :nodoc:
105
+ gem_root = File.expand_path("..", __dir__) + "/"
106
+ caller_locations(uplevel, 10).each do |frame|
107
+ if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
108
+ uplevel += 1
107
109
  else
108
- warn(message, uplevel: uplevel - 1)
110
+ break
109
111
  end
110
112
  end
113
+
114
+ if RUBY_VERSION >= "3.0"
115
+ warn(message, uplevel: uplevel, category: :deprecated)
116
+ else
117
+ warn(message, uplevel: uplevel)
118
+ end
111
119
  end
112
- end
113
120
 
114
- class << self
115
121
  # :call-seq:
116
122
  # JSON[object] -> new_array or new_string
117
123
  #
@@ -146,16 +152,6 @@ module JSON
146
152
  const_set :Parser, parser
147
153
  end
148
154
 
149
- # Return the constant located at _path_. The format of _path_ has to be
150
- # either ::A::B::C or A::B::C. In any case, A has to be located at the top
151
- # level (absolute namespace path?). If there doesn't exist a constant at
152
- # the given path, an ArgumentError is raised.
153
- def deep_const_get(path) # :nodoc:
154
- Object.const_get(path)
155
- rescue NameError => e
156
- raise ArgumentError, "can't get const #{path}: #{e}"
157
- end
158
-
159
155
  # Set the module _generator_ to be used by JSON.
160
156
  def generator=(generator) # :nodoc:
161
157
  old, $VERBOSE = $VERBOSE, nil
@@ -185,6 +181,25 @@ module JSON
185
181
 
186
182
  private
187
183
 
184
+ # Called from the extension when a hash has both string and symbol keys
185
+ def on_mixed_keys_hash(hash, do_raise)
186
+ set = {}
187
+ hash.each_key do |key|
188
+ key_str = key.to_s
189
+
190
+ if set[key_str]
191
+ message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
192
+ if do_raise
193
+ raise GeneratorError, message
194
+ else
195
+ deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
196
+ end
197
+ else
198
+ set[key_str] = true
199
+ end
200
+ end
201
+ end
202
+
188
203
  def deprecated_singleton_attr_accessor(*attrs)
189
204
  args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
190
205
  attrs.each do |attr|
@@ -268,7 +283,7 @@ module JSON
268
283
  # to string interpolation.
269
284
  #
270
285
  # Note: no validation is performed on the provided string. It is the
271
- # responsability of the caller to ensure the string contains valid JSON.
286
+ # responsibility of the caller to ensure the string contains valid JSON.
272
287
  Fragment = Struct.new(:json) do
273
288
  def initialize(json)
274
289
  unless string = String.try_convert(json)
@@ -390,7 +405,7 @@ module JSON
390
405
  #
391
406
  # Returns a \String containing the generated \JSON data.
392
407
  #
393
- # See also JSON.fast_generate, JSON.pretty_generate.
408
+ # See also JSON.pretty_generate.
394
409
  #
395
410
  # Argument +obj+ is the Ruby object to be converted to \JSON.
396
411
  #
@@ -642,6 +657,7 @@ module JSON
642
657
  # when Array
643
658
  # obj.map! {|v| deserialize_obj v }
644
659
  # end
660
+ # obj
645
661
  # })
646
662
  # pp ruby
647
663
  # Output:
@@ -683,9 +699,13 @@ module JSON
683
699
  if opts[:allow_blank] && (source.nil? || source.empty?)
684
700
  source = 'null'
685
701
  end
686
- result = parse(source, opts)
687
- recurse_proc(result, &proc) if proc
688
- result
702
+
703
+ if proc
704
+ opts = opts.dup
705
+ opts[:on_load] = proc.to_proc
706
+ end
707
+
708
+ parse(source, opts)
689
709
  end
690
710
 
691
711
  # :call-seq:
@@ -802,6 +822,7 @@ module JSON
802
822
  # when Array
803
823
  # obj.map! {|v| deserialize_obj v }
804
824
  # end
825
+ # obj
805
826
  # })
806
827
  # pp ruby
807
828
  # Output:
@@ -1001,7 +1022,7 @@ module JSON
1001
1022
  # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
1002
1023
  #
1003
1024
  # For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
1004
- # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1025
+ # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1005
1026
  # \JSON counterpart:
1006
1027
  #
1007
1028
  # module MyApp
@@ -8,20 +8,8 @@ module JSON
8
8
  #
9
9
  # Instantiates a new State object, configured by _opts_.
10
10
  #
11
- # _opts_ can have the following keys:
12
- #
13
- # * *indent*: a string used to indent levels (default: ''),
14
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
15
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
16
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
17
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
18
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
19
- # generated, otherwise an exception is thrown, if these values are
20
- # encountered. This options defaults to false.
21
- # * *ascii_only*: true if only ASCII characters should be generated. This
22
- # option defaults to false.
23
- # * *buffer_initial_length*: sets the initial length of the generator's
24
- # internal buffer.
11
+ # Argument +opts+, if given, contains a \Hash of options for the generation.
12
+ # See {Generating Options}[#module-JSON-label-Generating+Options].
25
13
  def initialize(opts = nil)
26
14
  if opts && !opts.empty?
27
15
  configure(opts)
@@ -68,6 +56,11 @@ module JSON
68
56
  buffer_initial_length: buffer_initial_length,
69
57
  }
70
58
 
59
+ allow_duplicate_key = allow_duplicate_key?
60
+ unless allow_duplicate_key.nil?
61
+ result[:allow_duplicate_key] = allow_duplicate_key
62
+ end
63
+
71
64
  instance_variables.each do |iv|
72
65
  iv = iv.to_s[1..-1]
73
66
  result[iv.to_sym] = self[iv]
@@ -82,6 +75,8 @@ module JSON
82
75
  #
83
76
  # Returns the value returned by method +name+.
84
77
  def [](name)
78
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
79
+
85
80
  if respond_to?(name)
86
81
  __send__(name)
87
82
  else
@@ -94,6 +89,8 @@ module JSON
94
89
  #
95
90
  # Sets the attribute name to value.
96
91
  def []=(name, value)
92
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
93
+
97
94
  if respond_to?(name_writer = "#{name}=")
98
95
  __send__ name_writer, value
99
96
  else
@@ -52,14 +52,6 @@ module JSON
52
52
  table
53
53
  end
54
54
 
55
- def [](name)
56
- __send__(name)
57
- end unless method_defined?(:[])
58
-
59
- def []=(name, value)
60
- __send__("#{name}=", value)
61
- end unless method_defined?(:[]=)
62
-
63
55
  def |(other)
64
56
  self.class[other.to_hash.merge(to_hash)]
65
57
  end
@@ -47,6 +47,19 @@ module JSON
47
47
 
48
48
  SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
49
49
 
50
+ def self.native_type?(value) # :nodoc:
51
+ (false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
52
+ end
53
+
54
+ def self.native_key?(key) # :nodoc:
55
+ (Symbol === key || String === key)
56
+ end
57
+
58
+ def self.valid_encoding?(string) # :nodoc:
59
+ return false unless string.encoding == ::Encoding::UTF_8 || string.encoding == ::Encoding::US_ASCII
60
+ string.is_a?(Symbol) || string.valid_encoding?
61
+ end
62
+
50
63
  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
51
64
  # UTF16 big endian characters as \u????, and return it.
52
65
  def self.utf8_to_json(string, script_safe = false) # :nodoc:
@@ -204,7 +217,7 @@ module JSON
204
217
  return if @max_nesting.zero?
205
218
  current_nesting = depth + 1
206
219
  current_nesting > @max_nesting and
207
- raise NestingError, "nesting of #{current_nesting} is too deep"
220
+ raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
208
221
  end
209
222
 
210
223
  # Returns true, if circular data structures are checked,
@@ -271,6 +284,12 @@ module JSON
271
284
  false
272
285
  end
273
286
 
287
+ if opts.key?(:allow_duplicate_key)
288
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
289
+ else
290
+ @allow_duplicate_key = nil # nil is deprecation
291
+ end
292
+
274
293
  @strict = !!opts[:strict] if opts.key?(:strict)
275
294
 
276
295
  if !opts.key?(:max_nesting) # defaults to 100
@@ -284,6 +303,10 @@ module JSON
284
303
  end
285
304
  alias merge configure
286
305
 
306
+ def allow_duplicate_key? # :nodoc:
307
+ @allow_duplicate_key
308
+ end
309
+
287
310
  # Returns the configuration instance variables as a hash, that can be
288
311
  # passed to the configure method.
289
312
  def to_h
@@ -292,6 +315,11 @@ module JSON
292
315
  iv = iv.to_s[1..-1]
293
316
  result[iv.to_sym] = self[iv]
294
317
  end
318
+
319
+ if result[:allow_duplicate_key].nil?
320
+ result.delete(:allow_duplicate_key)
321
+ end
322
+
295
323
  result
296
324
  end
297
325
 
@@ -324,14 +352,27 @@ module JSON
324
352
  dup.generate(obj, anIO)
325
353
  end
326
354
 
355
+ private def initialize_copy(_orig)
356
+ @depth = 0
357
+ end
358
+
327
359
  # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
328
360
  private def generate_json(obj, buf)
329
361
  case obj
330
362
  when Hash
331
363
  buf << '{'
332
364
  first = true
365
+ key_type = nil
333
366
  obj.each_pair do |k,v|
334
- buf << ',' unless first
367
+ if first
368
+ key_type = k.class
369
+ else
370
+ if key_type && !@allow_duplicate_key && key_type != k.class
371
+ key_type = nil # stop checking
372
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
373
+ end
374
+ buf << ','
375
+ end
335
376
 
336
377
  key_str = k.to_s
337
378
  if key_str.class == String
@@ -398,6 +439,8 @@ module JSON
398
439
 
399
440
  # Return the value returned by method +name+.
400
441
  def [](name)
442
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
443
+
401
444
  if respond_to?(name)
402
445
  __send__(name)
403
446
  else
@@ -407,6 +450,8 @@ module JSON
407
450
  end
408
451
 
409
452
  def []=(name, value)
453
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
454
+
410
455
  if respond_to?(name_writer = "#{name}=")
411
456
  __send__ name_writer, value
412
457
  else
@@ -424,10 +469,10 @@ module JSON
424
469
  state = State.from_state(state) if state
425
470
  if state&.strict?
426
471
  value = self
427
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
472
+ if state.strict? && !Generator.native_type?(value)
428
473
  if state.as_json
429
- value = state.as_json.call(value)
430
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
474
+ value = state.as_json.call(value, false)
475
+ unless Generator.native_type?(value)
431
476
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
432
477
  end
433
478
  value.to_json(state)
@@ -471,11 +516,34 @@ module JSON
471
516
  delim = ",#{state.object_nl}"
472
517
  result = +"{#{state.object_nl}"
473
518
  first = true
519
+ key_type = nil
474
520
  indent = !state.object_nl.empty?
475
521
  each { |key, value|
476
- result << delim unless first
522
+ if first
523
+ key_type = key.class
524
+ else
525
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
526
+ key_type = nil # stop checking
527
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
528
+ end
529
+ result << delim
530
+ end
477
531
  result << state.indent * depth if indent
478
532
 
533
+ if state.strict?
534
+ if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
535
+ key = state.as_json.call(key, true)
536
+ end
537
+
538
+ unless Generator.native_key?(key)
539
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
540
+ end
541
+
542
+ unless Generator.valid_encoding?(key)
543
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
544
+ end
545
+ end
546
+
479
547
  key_str = key.to_s
480
548
  if key_str.is_a?(String)
481
549
  key_json = key_str.to_json(state)
@@ -484,10 +552,10 @@ module JSON
484
552
  end
485
553
 
486
554
  result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
487
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
555
+ if state.strict? && !Generator.native_type?(value)
488
556
  if state.as_json
489
- value = state.as_json.call(value)
490
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
557
+ value = state.as_json.call(value, false)
558
+ unless Generator.native_type?(value)
491
559
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
492
560
  end
493
561
  result << value.to_json(state)
@@ -545,10 +613,10 @@ module JSON
545
613
  each { |value|
546
614
  result << delim unless first
547
615
  result << state.indent * depth if indent
548
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value)
616
+ if state.strict? && !Generator.native_type?(value)
549
617
  if state.as_json
550
- value = state.as_json.call(value)
551
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value
618
+ value = state.as_json.call(value, false)
619
+ unless Generator.native_type?(value)
552
620
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
553
621
  end
554
622
  result << value.to_json(state)
@@ -582,7 +650,7 @@ module JSON
582
650
  if state.allow_nan?
583
651
  to_s
584
652
  elsif state.strict? && state.as_json
585
- casted_value = state.as_json.call(self)
653
+ casted_value = state.as_json.call(self, false)
586
654
 
587
655
  if casted_value.equal?(self)
588
656
  raise GeneratorError.new("#{self} not allowed in JSON", self)
@@ -619,14 +687,25 @@ module JSON
619
687
  # \u????.
620
688
  def to_json(state = nil, *args)
621
689
  state = State.from_state(state)
622
- if encoding == ::Encoding::UTF_8
623
- unless valid_encoding?
690
+ string = self
691
+
692
+ if state.strict? && state.as_json
693
+ unless Generator.valid_encoding?(string)
694
+ string = state.as_json.call(string, false)
695
+ unless string.is_a?(::String)
696
+ return string.to_json(state, *args)
697
+ end
698
+ end
699
+ end
700
+
701
+ if string.encoding == ::Encoding::UTF_8
702
+ unless string.valid_encoding?
624
703
  raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
625
704
  end
626
- string = self
627
705
  else
628
- string = encode(::Encoding::UTF_8)
706
+ string = string.encode(::Encoding::UTF_8)
629
707
  end
708
+
630
709
  if state.ascii_only?
631
710
  %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
632
711
  else
@@ -635,39 +714,6 @@ module JSON
635
714
  rescue Encoding::UndefinedConversionError => error
636
715
  raise ::JSON::GeneratorError.new(error.message, self)
637
716
  end
638
-
639
- # Module that holds the extending methods if, the String module is
640
- # included.
641
- module Extend
642
- # Raw Strings are JSON Objects (the raw bytes are stored in an
643
- # array for the key "raw"). The Ruby String can be created by this
644
- # module method.
645
- def json_create(o)
646
- o['raw'].pack('C*')
647
- end
648
- end
649
-
650
- # Extends _modul_ with the String::Extend module.
651
- def self.included(modul)
652
- modul.extend Extend
653
- end
654
-
655
- # This method creates a raw object hash, that can be nested into
656
- # other data structures and will be unparsed as a raw string. This
657
- # method should be used, if you want to convert raw strings to JSON
658
- # instead of UTF-8 strings, e. g. binary data.
659
- def to_json_raw_object
660
- {
661
- JSON.create_id => self.class.name,
662
- 'raw' => self.unpack('C*'),
663
- }
664
- end
665
-
666
- # This method creates a JSON text from the result of
667
- # a call to to_json_raw_object of this String.
668
- def to_json_raw(*args)
669
- to_json_raw_object.to_json(*args)
670
- end
671
717
  end
672
718
 
673
719
  module TrueClass
data/lib/json/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.12.2'
4
+ VERSION = '2.16.0'
5
5
  end
data/lib/json.rb CHANGED
@@ -127,6 +127,24 @@ require 'json/common'
127
127
  #
128
128
  # ---
129
129
  #
130
+ # Option +allow_duplicate_key+ specifies whether duplicate keys in objects
131
+ # should be ignored or cause an error to be raised:
132
+ #
133
+ # When not specified:
134
+ # # The last value is used and a deprecation warning emitted.
135
+ # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
136
+ # # warning: detected duplicate keys in JSON object.
137
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
138
+ #
139
+ # When set to `+true+`
140
+ # # The last value is used.
141
+ # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
142
+ #
143
+ # When set to `+false+`, the future default:
144
+ # JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
145
+ #
146
+ # ---
147
+ #
130
148
  # Option +allow_nan+ (boolean) specifies whether to allow
131
149
  # NaN, Infinity, and MinusInfinity in +source+;
132
150
  # defaults to +false+.
@@ -143,8 +161,23 @@ require 'json/common'
143
161
  # ruby = JSON.parse(source, {allow_nan: true})
144
162
  # ruby # => [NaN, Infinity, -Infinity]
145
163
  #
164
+ # ---
165
+ #
166
+ # Option +allow_trailing_comma+ (boolean) specifies whether to allow
167
+ # trailing commas in objects and arrays;
168
+ # defaults to +false+.
169
+ #
170
+ # With the default, +false+:
171
+ # JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError)
172
+ #
173
+ # When enabled:
174
+ # JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
175
+ #
146
176
  # ====== Output Options
147
177
  #
178
+ # Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
179
+ # defaults to +false+.
180
+ #
148
181
  # Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
149
182
  # should be Symbols;
150
183
  # defaults to +false+ (use Strings).
@@ -274,6 +307,25 @@ require 'json/common'
274
307
  #
275
308
  # ---
276
309
  #
310
+ # Option +allow_duplicate_key+ (boolean) specifies whether
311
+ # hashes with duplicate keys should be allowed or produce an error.
312
+ # defaults to emit a deprecation warning.
313
+ #
314
+ # With the default, (not set):
315
+ # Warning[:deprecated] = true
316
+ # JSON.generate({ foo: 1, "foo" => 2 })
317
+ # # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
318
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
319
+ # # => '{"foo":1,"foo":2}'
320
+ #
321
+ # With <tt>false</tt>
322
+ # JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
323
+ # # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
324
+ #
325
+ # In version 3.0, <tt>false</tt> will become the default.
326
+ #
327
+ # ---
328
+ #
277
329
  # Option +max_nesting+ (\Integer) specifies the maximum nesting depth
278
330
  # in +obj+; defaults to +100+.
279
331
  #
@@ -351,6 +403,9 @@ require 'json/common'
351
403
  #
352
404
  # == \JSON Additions
353
405
  #
406
+ # Note that JSON Additions must only be used with trusted data, and is
407
+ # deprecated.
408
+ #
354
409
  # When you "round trip" a non-\String object from Ruby to \JSON and back,
355
410
  # you have a new \String, instead of the object you began with:
356
411
  # ruby0 = Range.new(0, 2)