json 2.3.1 → 2.5.1
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 +22 -0
- data/LICENSE +56 -0
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +60 -11
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/extconf.rb +25 -0
- data/ext/json/ext/parser/parser.c +110 -68
- data/ext/json/ext/parser/parser.h +1 -0
- data/ext/json/ext/parser/parser.rl +67 -25
- data/ext/json/extconf.rb +1 -0
- data/json.gemspec +11 -77
- data/lib/json.rb +171 -0
- data/lib/json/add/complex.rb +0 -1
- data/lib/json/add/rational.rb +0 -1
- data/lib/json/common.rb +240 -228
- data/lib/json/pure/generator.rb +28 -8
- data/lib/json/pure/parser.rb +20 -2
- data/lib/json/version.rb +1 -1
- data/tests/fixtures/fail29.json +1 -0
- data/tests/fixtures/fail30.json +1 -0
- data/tests/fixtures/fail31.json +1 -0
- data/tests/fixtures/fail32.json +1 -0
- data/tests/json_addition_test.rb +0 -4
- data/tests/json_common_interface_test.rb +43 -0
- data/tests/json_fixtures_test.rb +3 -0
- data/tests/json_generator_test.rb +16 -38
- data/tests/json_parser_test.rb +25 -0
- data/tests/lib/core_assertions.rb +763 -0
- data/tests/lib/envutil.rb +365 -0
- data/tests/lib/find_executable.rb +22 -0
- data/tests/lib/helper.rb +4 -0
- data/tests/ractor_test.rb +30 -0
- data/tests/test_helper.rb +3 -3
- metadata +16 -37
- data/.gitignore +0 -18
- data/.travis.yml +0 -26
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -334
- data/diagrams/.keep +0 -0
- data/install.rb +0 -23
- data/java/src/json/ext/ByteListTranscoder.java +0 -166
- data/java/src/json/ext/Generator.java +0 -466
- data/java/src/json/ext/GeneratorMethods.java +0 -231
- data/java/src/json/ext/GeneratorService.java +0 -42
- data/java/src/json/ext/GeneratorState.java +0 -490
- data/java/src/json/ext/OptionsReader.java +0 -113
- data/java/src/json/ext/Parser.java +0 -2362
- data/java/src/json/ext/Parser.rl +0 -893
- data/java/src/json/ext/ParserService.java +0 -34
- data/java/src/json/ext/RuntimeInfo.java +0 -116
- data/java/src/json/ext/StringDecoder.java +0 -166
- data/java/src/json/ext/StringEncoder.java +0 -111
- data/java/src/json/ext/Utils.java +0 -88
- data/json-java.gemspec +0 -37
- data/json_pure.gemspec +0 -33
- data/references/rfc7159.txt +0 -899
- data/tools/diff.sh +0 -18
- data/tools/fuzz.rb +0 -131
- data/tools/server.rb +0 -62
@@ -89,13 +89,12 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
89
89
|
|
90
90
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
91
91
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
92
|
-
static VALUE cBigDecimal = Qundef;
|
93
92
|
|
94
93
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
95
94
|
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
96
95
|
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
97
96
|
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
98
|
-
i_leftshift, i_new,
|
97
|
+
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
|
99
98
|
|
100
99
|
%%{
|
101
100
|
machine JSON_common;
|
@@ -290,6 +289,10 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
290
289
|
%% write init;
|
291
290
|
%% write exec;
|
292
291
|
|
292
|
+
if (json->freeze) {
|
293
|
+
OBJ_FREEZE(*result);
|
294
|
+
}
|
295
|
+
|
293
296
|
if (cs >= JSON_value_first_final) {
|
294
297
|
return p;
|
295
298
|
} else {
|
@@ -341,19 +344,6 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
341
344
|
) (^[0-9Ee.\-]? @exit );
|
342
345
|
}%%
|
343
346
|
|
344
|
-
static int is_bigdecimal_class(VALUE obj)
|
345
|
-
{
|
346
|
-
if (cBigDecimal == Qundef) {
|
347
|
-
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
|
348
|
-
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
|
349
|
-
}
|
350
|
-
else {
|
351
|
-
return 0;
|
352
|
-
}
|
353
|
-
}
|
354
|
-
return obj == cBigDecimal;
|
355
|
-
}
|
356
|
-
|
357
347
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
358
348
|
{
|
359
349
|
int cs = EVIL;
|
@@ -363,21 +353,46 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
363
353
|
%% write exec;
|
364
354
|
|
365
355
|
if (cs >= JSON_float_first_final) {
|
356
|
+
VALUE mod = Qnil;
|
357
|
+
ID method_id = 0;
|
358
|
+
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
359
|
+
mod = json->decimal_class;
|
360
|
+
method_id = i_try_convert;
|
361
|
+
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
362
|
+
mod = json->decimal_class;
|
363
|
+
method_id = i_new;
|
364
|
+
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
365
|
+
VALUE name = rb_class_name(json->decimal_class);
|
366
|
+
const char *name_cstr = RSTRING_PTR(name);
|
367
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
368
|
+
if (last_colon) {
|
369
|
+
const char *mod_path_end = last_colon - 1;
|
370
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
371
|
+
mod = rb_path_to_class(mod_path);
|
372
|
+
|
373
|
+
const char *method_name_beg = last_colon + 1;
|
374
|
+
long before_len = method_name_beg - name_cstr;
|
375
|
+
long len = RSTRING_LEN(name) - before_len;
|
376
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
377
|
+
method_id = SYM2ID(rb_str_intern(method_name));
|
378
|
+
} else {
|
379
|
+
mod = rb_mKernel;
|
380
|
+
method_id = SYM2ID(rb_str_intern(name));
|
381
|
+
}
|
382
|
+
}
|
383
|
+
|
366
384
|
long len = p - json->memo;
|
367
385
|
fbuffer_clear(json->fbuffer);
|
368
386
|
fbuffer_append(json->fbuffer, json->memo, len);
|
369
387
|
fbuffer_append_char(json->fbuffer, '\0');
|
370
|
-
|
371
|
-
|
388
|
+
|
389
|
+
if (method_id) {
|
390
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
391
|
+
*result = rb_funcallv(mod, method_id, 1, &text);
|
372
392
|
} else {
|
373
|
-
|
374
|
-
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
375
|
-
if (is_bigdecimal_class(json->decimal_class)) {
|
376
|
-
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
|
377
|
-
} else {
|
378
|
-
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
379
|
-
}
|
393
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
380
394
|
}
|
395
|
+
|
381
396
|
return p + 1;
|
382
397
|
} else {
|
383
398
|
return NULL;
|
@@ -573,7 +588,22 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
573
588
|
if (json->symbolize_names && json->parsing_name) {
|
574
589
|
*result = rb_str_intern(*result);
|
575
590
|
} else if (RB_TYPE_P(*result, T_STRING)) {
|
591
|
+
# if STR_UMINUS_DEDUPE_FROZEN
|
592
|
+
if (json->freeze) {
|
593
|
+
// Starting from MRI 2.8 it is preferable to freeze the string
|
594
|
+
// before deduplication so that it can be interned directly
|
595
|
+
// otherwise it would be duplicated first which is wasteful.
|
596
|
+
*result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
|
597
|
+
}
|
598
|
+
# elif STR_UMINUS_DEDUPE
|
599
|
+
if (json->freeze) {
|
600
|
+
// MRI 2.5 and older do not deduplicate strings that are already
|
601
|
+
// frozen.
|
602
|
+
*result = rb_funcall(*result, i_uminus, 0);
|
603
|
+
}
|
604
|
+
# else
|
576
605
|
rb_str_resize(*result, RSTRING_LEN(*result));
|
606
|
+
# endif
|
577
607
|
}
|
578
608
|
if (cs >= JSON_string_first_final) {
|
579
609
|
return p + 1;
|
@@ -681,6 +711,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
681
711
|
} else {
|
682
712
|
json->symbolize_names = 0;
|
683
713
|
}
|
714
|
+
tmp = ID2SYM(i_freeze);
|
715
|
+
if (option_given_p(opts, tmp)) {
|
716
|
+
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
717
|
+
} else {
|
718
|
+
json->freeze = 0;
|
719
|
+
}
|
684
720
|
tmp = ID2SYM(i_create_additions);
|
685
721
|
if (option_given_p(opts, tmp)) {
|
686
722
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -843,6 +879,10 @@ static VALUE cParser_source(VALUE self)
|
|
843
879
|
|
844
880
|
void Init_parser(void)
|
845
881
|
{
|
882
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
883
|
+
rb_ext_ractor_safe(true);
|
884
|
+
#endif
|
885
|
+
|
846
886
|
#undef rb_intern
|
847
887
|
rb_require("json/common");
|
848
888
|
mJSON = rb_define_module("JSON");
|
@@ -885,7 +925,9 @@ void Init_parser(void)
|
|
885
925
|
i_aref = rb_intern("[]");
|
886
926
|
i_leftshift = rb_intern("<<");
|
887
927
|
i_new = rb_intern("new");
|
888
|
-
|
928
|
+
i_try_convert = rb_intern("try_convert");
|
929
|
+
i_freeze = rb_intern("freeze");
|
930
|
+
i_uminus = rb_intern("-@");
|
889
931
|
}
|
890
932
|
|
891
933
|
/*
|
data/ext/json/extconf.rb
CHANGED
data/json.gemspec
CHANGED
@@ -2,25 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "json"
|
5
|
-
s.version = File.read('VERSION').chomp
|
5
|
+
s.version = File.read(File.expand_path('../VERSION', __FILE__)).chomp
|
6
6
|
|
7
|
-
s.
|
8
|
-
s.require_paths = ["lib"]
|
9
|
-
s.authors = ["Florian Frank"]
|
7
|
+
s.summary = "JSON Implementation for Ruby"
|
10
8
|
s.description = "This is a JSON implementation as a Ruby extension in C."
|
9
|
+
s.licenses = ["Ruby"]
|
10
|
+
s.authors = ["Florian Frank"]
|
11
11
|
s.email = "flori@ping.de"
|
12
|
+
|
12
13
|
s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb", "ext/json/extconf.rb"]
|
13
14
|
s.extra_rdoc_files = ["README.md"]
|
15
|
+
s.rdoc_options = ["--title", "JSON implementation for Ruby", "--main", "README.md"]
|
14
16
|
s.files = [
|
15
|
-
".gitignore",
|
16
|
-
".travis.yml",
|
17
17
|
"CHANGES.md",
|
18
18
|
"Gemfile",
|
19
|
-
"
|
19
|
+
"LICENSE",
|
20
20
|
"README.md",
|
21
|
-
"Rakefile",
|
22
21
|
"VERSION",
|
23
|
-
"diagrams/.keep",
|
24
22
|
"ext/json/ext/fbuffer/fbuffer.h",
|
25
23
|
"ext/json/ext/generator/depend",
|
26
24
|
"ext/json/ext/generator/extconf.rb",
|
@@ -32,23 +30,7 @@ Gem::Specification.new do |s|
|
|
32
30
|
"ext/json/ext/parser/parser.h",
|
33
31
|
"ext/json/ext/parser/parser.rl",
|
34
32
|
"ext/json/extconf.rb",
|
35
|
-
"install.rb",
|
36
|
-
"java/src/json/ext/ByteListTranscoder.java",
|
37
|
-
"java/src/json/ext/Generator.java",
|
38
|
-
"java/src/json/ext/GeneratorMethods.java",
|
39
|
-
"java/src/json/ext/GeneratorService.java",
|
40
|
-
"java/src/json/ext/GeneratorState.java",
|
41
|
-
"java/src/json/ext/OptionsReader.java",
|
42
|
-
"java/src/json/ext/Parser.java",
|
43
|
-
"java/src/json/ext/Parser.rl",
|
44
|
-
"java/src/json/ext/ParserService.java",
|
45
|
-
"java/src/json/ext/RuntimeInfo.java",
|
46
|
-
"java/src/json/ext/StringDecoder.java",
|
47
|
-
"java/src/json/ext/StringEncoder.java",
|
48
|
-
"java/src/json/ext/Utils.java",
|
49
|
-
"json-java.gemspec",
|
50
33
|
"json.gemspec",
|
51
|
-
"json_pure.gemspec",
|
52
34
|
"lib/json.rb",
|
53
35
|
"lib/json/add/bigdecimal.rb",
|
54
36
|
"lib/json/add/complex.rb",
|
@@ -72,53 +54,7 @@ Gem::Specification.new do |s|
|
|
72
54
|
"lib/json/pure/generator.rb",
|
73
55
|
"lib/json/pure/parser.rb",
|
74
56
|
"lib/json/version.rb",
|
75
|
-
|
76
|
-
"tests/fixtures/fail10.json",
|
77
|
-
"tests/fixtures/fail11.json",
|
78
|
-
"tests/fixtures/fail12.json",
|
79
|
-
"tests/fixtures/fail13.json",
|
80
|
-
"tests/fixtures/fail14.json",
|
81
|
-
"tests/fixtures/fail18.json",
|
82
|
-
"tests/fixtures/fail19.json",
|
83
|
-
"tests/fixtures/fail2.json",
|
84
|
-
"tests/fixtures/fail20.json",
|
85
|
-
"tests/fixtures/fail21.json",
|
86
|
-
"tests/fixtures/fail22.json",
|
87
|
-
"tests/fixtures/fail23.json",
|
88
|
-
"tests/fixtures/fail24.json",
|
89
|
-
"tests/fixtures/fail25.json",
|
90
|
-
"tests/fixtures/fail27.json",
|
91
|
-
"tests/fixtures/fail28.json",
|
92
|
-
"tests/fixtures/fail3.json",
|
93
|
-
"tests/fixtures/fail4.json",
|
94
|
-
"tests/fixtures/fail5.json",
|
95
|
-
"tests/fixtures/fail6.json",
|
96
|
-
"tests/fixtures/fail7.json",
|
97
|
-
"tests/fixtures/fail8.json",
|
98
|
-
"tests/fixtures/fail9.json",
|
99
|
-
"tests/fixtures/obsolete_fail1.json",
|
100
|
-
"tests/fixtures/pass1.json",
|
101
|
-
"tests/fixtures/pass15.json",
|
102
|
-
"tests/fixtures/pass16.json",
|
103
|
-
"tests/fixtures/pass17.json",
|
104
|
-
"tests/fixtures/pass2.json",
|
105
|
-
"tests/fixtures/pass26.json",
|
106
|
-
"tests/fixtures/pass3.json",
|
107
|
-
"tests/json_addition_test.rb",
|
108
|
-
"tests/json_common_interface_test.rb",
|
109
|
-
"tests/json_encoding_test.rb",
|
110
|
-
"tests/json_ext_parser_test.rb",
|
111
|
-
"tests/json_fixtures_test.rb",
|
112
|
-
"tests/json_generator_test.rb",
|
113
|
-
"tests/json_generic_object_test.rb",
|
114
|
-
"tests/json_parser_test.rb",
|
115
|
-
"tests/json_string_matching_test.rb",
|
116
|
-
"tests/test_helper.rb",
|
117
|
-
"tests/test_helper.rb",
|
118
|
-
"tools/diff.sh",
|
119
|
-
"tools/fuzz.rb",
|
120
|
-
"tools/server.rb",
|
121
|
-
]
|
57
|
+
] + Dir["tests/**/*"]
|
122
58
|
s.homepage = "http://flori.github.com/json"
|
123
59
|
s.metadata = {
|
124
60
|
'bug_tracker_uri' => 'https://github.com/flori/json/issues',
|
@@ -128,12 +64,10 @@ Gem::Specification.new do |s|
|
|
128
64
|
'source_code_uri' => 'https://github.com/flori/json',
|
129
65
|
'wiki_uri' => 'https://github.com/flori/json/wiki'
|
130
66
|
}
|
131
|
-
|
132
|
-
s.rdoc_options = ["--title", "JSON implemention for Ruby", "--main", "README.md"]
|
67
|
+
|
133
68
|
s.required_ruby_version = Gem::Requirement.new(">= 2.0")
|
134
|
-
s.summary = "JSON Implementation for Ruby"
|
135
69
|
s.test_files = ["tests/test_helper.rb"]
|
136
70
|
|
137
|
-
s.add_development_dependency
|
138
|
-
s.add_development_dependency
|
71
|
+
s.add_development_dependency "rake"
|
72
|
+
s.add_development_dependency "test-unit"
|
139
73
|
end
|
data/lib/json.rb
CHANGED
@@ -107,6 +107,89 @@ require 'json/common'
|
|
107
107
|
# ruby # => nil
|
108
108
|
# ruby.class # => NilClass
|
109
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
|
+
#
|
110
193
|
# === Generating \JSON
|
111
194
|
#
|
112
195
|
# To generate a Ruby \String containing \JSON data,
|
@@ -169,6 +252,94 @@ require 'json/common'
|
|
169
252
|
# JSON.generate(Complex(0, 0)) # => '"0+0i"'
|
170
253
|
# JSON.generate(Dir.new('.')) # => '"#<Dir>"'
|
171
254
|
#
|
255
|
+
# ==== Generating Options
|
256
|
+
#
|
257
|
+
# ====== Input Options
|
258
|
+
#
|
259
|
+
# Option +allow_nan+ (boolean) specifies whether
|
260
|
+
# +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
|
261
|
+
# defaults to +false+.
|
262
|
+
#
|
263
|
+
# With the default, +false+:
|
264
|
+
# # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
|
265
|
+
# JSON.generate(JSON::NaN)
|
266
|
+
# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
|
267
|
+
# JSON.generate(JSON::Infinity)
|
268
|
+
# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
|
269
|
+
# JSON.generate(JSON::MinusInfinity)
|
270
|
+
#
|
271
|
+
# Allow:
|
272
|
+
# ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
|
273
|
+
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
|
274
|
+
#
|
275
|
+
# ---
|
276
|
+
#
|
277
|
+
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth
|
278
|
+
# in +obj+; defaults to +100+.
|
279
|
+
#
|
280
|
+
# With the default, +100+:
|
281
|
+
# obj = [[[[[[0]]]]]]
|
282
|
+
# JSON.generate(obj) # => '[[[[[[0]]]]]]'
|
283
|
+
#
|
284
|
+
# Too deep:
|
285
|
+
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
286
|
+
# JSON.generate(obj, max_nesting: 2)
|
287
|
+
#
|
288
|
+
# ====== 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
|
+
#
|
172
343
|
# == \JSON Additions
|
173
344
|
#
|
174
345
|
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|