diff --git a/lib/json.rb b/lib/json.rb
index 1e7573df..f5f5ade8 100644
--- a/lib/json.rb
+++ b/lib/json.rb
@@ -44,13 +44,13 @@
#
# You can parse a \String containing \JSON data using
# either of two methods:
-# - JSON.parse(source, opts)
-# - JSON.parse!(source, opts)
+# - JSON.parse(source, **opts)
+# - JSON.parse!(source, **opts)
#
# where
# - +source+ is a Ruby object.
-# - +opts+ is a \Hash object containing options
-# that control both input allowed and output formatting.
+# - +opts+ are keyword arguments that control both input
+# allowed and output formatting.
#
# The difference between the two methods
# is that JSON.parse! omits some checks
@@ -102,7 +102,7 @@
# ruby # => 1.0
# ruby.class # => Float
# ruby = JSON.parse('2.0e2')
-# ruby # => 200
+# ruby # => 200.0
# ruby.class # => Float
# Boolean:
# ruby = JSON.parse('true')
@@ -131,10 +131,10 @@
# ruby # => [0, [1, [2, [3]]]]
# Too deep:
# # Raises JSON::NestingError (nesting of 2 is too deep):
-# JSON.parse(source, {max_nesting: 1})
+# JSON.parse(source, max_nesting: 1)
# Bad value:
-# # Raises TypeError (wrong argument type Symbol (expected Fixnum)):
-# JSON.parse(source, {max_nesting: :foo})
+# # Raises TypeError (no implicit conversion of Symbol into Integer):
+# JSON.parse(source, max_nesting: :foo)
#
# ---
#
@@ -142,11 +142,11 @@
# should be ignored or cause an error to be raised:
#
# When set to +false+, the default:
-# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
+# JSON.parse('{"a": 1, "a": 2}') # duplicate key "a" at line 1 column 1 (JSON::ParserError)
#
# When set to +true+:
# # The last value is used.
-# JSON.parse('{"a": 1, "a":2}', allow_duplicate_key: true) => {"a" => 2}
+# JSON.parse('{"a": 1, "a": 2}', allow_duplicate_key: true) # => {"a" => 2}
#
# ---
#
@@ -155,15 +155,15 @@
# defaults to +false+.
#
# With the default, +false+:
-# # Raises JSON::ParserError (225: unexpected token at '[NaN]'):
+# # Raises JSON::ParserError (unexpected token 'NaN]' at line 1 column 2):
# JSON.parse('[NaN]')
-# # Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
+# # Raises JSON::ParserError (unexpected token 'Infinity]' at line 1 column 2):
# JSON.parse('[Infinity]')
-# # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
+# # Raises JSON::ParserError (invalid number: '-Infinity]' at line 1 column 2):
# JSON.parse('[-Infinity]')
# Allow:
# source = '[NaN, Infinity, -Infinity]'
-# ruby = JSON.parse(source, {allow_nan: true})
+# ruby = JSON.parse(source, allow_nan: true)
# ruby # => [NaN, Infinity, -Infinity]
#
# ---
@@ -185,10 +185,10 @@
# defaults to +false+.
#
# When set to +false+, the default:
-# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
+# JSON.parse('/* comment */ {"a": 1, "a": 2}') # unexpected token '/*' at line 1 column 1 (JSON::ParserError)
#
# When set to +true+, comments are ignored:
-# JSON.parse('/* comment */ {"a": 1, "a":2} // more comment') # => {"a" => 2}
+# JSON.parse('/* comment */ {"a": 1} // more comment', allow_comments: true) # => {"a" => 1}
#
# ---
#
@@ -197,7 +197,7 @@
# defaults to +false+.
#
# With the default, +false+:
-# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
+# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string: \nWorld" at line 2 column 0 (JSON::ParserError)
#
# When enabled:
# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
@@ -209,7 +209,7 @@
# defaults to +false+.
#
# With the default, +false+:
-# JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
+# JSON.parse('"Hell\o"') # invalid escape character in string: '\o"' at line 1 column 6 (JSON::ParserError)
#
# When enabled:
# JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
@@ -228,8 +228,8 @@
# ruby = JSON.parse(source)
# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
# Use Symbols:
-# ruby = JSON.parse(source, {symbolize_names: true})
-# ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
+# ruby = JSON.parse(source, symbolize_names: true)
+# ruby # => {a: "foo", b: 1.0, c: true, d: false, e: nil}
#
# ---
#
@@ -242,7 +242,7 @@
# ruby = JSON.parse(source)
# ruby.class # => Hash
# Use class \OpenStruct:
-# ruby = JSON.parse(source, {object_class: OpenStruct})
+# ruby = JSON.parse(source, object_class: OpenStruct)
# ruby # => #
#
# ---
@@ -256,8 +256,8 @@
# ruby = JSON.parse(source)
# ruby.class # => Array
# Use class \Set:
-# ruby = JSON.parse(source, {array_class: Set})
-# ruby # => #
+# ruby = JSON.parse(source, array_class: Set)
+# ruby # => Set["foo", 1.0, true, false, nil]
#
# === Generating \JSON
#
@@ -319,22 +319,22 @@
# a \String containing a \JSON string representation of the source:
# JSON.generate(:foo) # => '"foo"'
# JSON.generate(Complex(0, 0)) # => '"0+0i"'
-# JSON.generate(Dir.new('.')) # => '"#"'
+# JSON.generate(Dir.new('.')) # => '"#"'
#
# ==== Generating Options
#
# ====== Input Options
#
# Option +allow_nan+ (boolean) specifies whether
-# +NaN+, +Infinity+, and -Infinity may be generated;
+# +NaN+, +Infinity+, and +-Infinity+ may be generated;
# defaults to +false+.
#
# With the default, +false+:
-# # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
+# # Raises JSON::GeneratorError (NaN not allowed in JSON):
# JSON.generate(JSON::NaN)
-# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
+# # Raises JSON::GeneratorError (Infinity not allowed in JSON):
# JSON.generate(JSON::Infinity)
-# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
+# # Raises JSON::GeneratorError (-Infinity not allowed in JSON):
# JSON.generate(JSON::MinusInfinity)
#
# Allow:
@@ -345,14 +345,14 @@
#
# Option +allow_duplicate_key+ (boolean) specifies whether
# hashes with duplicate keys should be allowed or produce an error.
-# defaults to emit a deprecation warning.
+# Defaults to +false+, which raises an error.
#
-# With the default, false:
-# JSON.generate({ foo: 1, "foo" => 2 })
+# With the default, +false+:
+# JSON.generate({foo: 1, "foo" => 2})
# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
#
-# With true
-# JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: true)
+# With +true+:
+# JSON.generate({foo: 1, "foo" => 2}, allow_duplicate_key: true)
# # => '{"foo":1,"foo":2}'
#
# ---
@@ -365,13 +365,13 @@
# JSON.generate(obj) # => '[[[[[[0]]]]]]'
#
# Too deep:
-# # Raises JSON::NestingError (nesting of 2 is too deep):
+# # Raises JSON::NestingError (nesting of 2 is too deep. Did you try to serialize objects with circular references?):
# JSON.generate(obj, max_nesting: 2)
#
# With +false+:
# obj = []
# obj[0] = obj
-# # Raises SystemStackError: stack level too deep
+# # Raises SystemStackError (stack level too deep):
# JSON.generate(obj, max_nesting: false)
#
# Setting +max_nesting+ to +false+ or a very large number can lead to a stack overflow
@@ -410,7 +410,7 @@
# inserted before the colon in each \JSON object's pair;
# defaults to the empty \String, ''.
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
-# hash are sorted when generating the output; defaults to false.
+# hash are sorted when generating the output; defaults to +false+.
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
# the entire \Hash and must return a \Hash with its pairs in the desired
# order, allowing for arbitrary sort orders.
@@ -439,7 +439,7 @@
# "foo" : [
# "bar",
# "baz"
-# ],
+# ],
# "bat" : {
# "bam" : 0,
# "bad" : 1
diff --git a/lib/json/common.rb b/lib/json/common.rb
index edcd93d4..ebec553a 100644
--- a/lib/json/common.rb
+++ b/lib/json/common.rb
@@ -143,11 +143,11 @@ class JSONError < StandardError; end
# This exception is raised if a parser error occurs.
class ParserError < JSONError
# Line number where the parser encountered an error.
- # Is nil when raised by JSON::ResumableParser.
+ # Is +nil+ when raised by JSON::ResumableParser.
attr_reader :line
# Column number where the parser encountered an error.
- # Is nil when raised by JSON::ResumableParser.
+ # Is +nil+ when raised by JSON::ResumableParser.
attr_reader :column
# Returns a best effort JSONPath string representing where in the document
@@ -290,7 +290,7 @@ def to_json(state = nil, *)
# ---
#
# Raises an exception if +source+ is not valid JSON:
- # # Raises JSON::ParserError unexpected character: 'invalid' at line 1 column 1 :
+ # # Raises JSON::ParserError (unexpected character: 'invalid' at line 1 column 1):
# JSON.parse('invalid')
#
def parse(source, on_load: nil, object_class: nil, array_class: nil, **options)
@@ -372,7 +372,7 @@ def load_file!(filespec, **options)
#
# Raises an exception if +obj+ contains circular references:
# a = []; b = []; a.push(b); b.push(a)
- # # Raises JSON::NestingError (nesting of 100 is too deep):
+ # # Raises JSON::NestingError (nesting of 100 is too deep. Did you try to serialize objects with circular references?):
# JSON.generate(a)
#
def generate(obj, opts = nil)