json_pure 2.7.4 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/json/common.rb DELETED
@@ -1,729 +0,0 @@
1
- #frozen_string_literal: true
2
- require 'json/version'
3
-
4
- module JSON
5
- autoload :GenericObject, 'json/generic_object'
6
-
7
- NOT_SET = Object.new.freeze
8
- private_constant :NOT_SET
9
-
10
- class << self
11
- # :call-seq:
12
- # JSON[object] -> new_array or new_string
13
- #
14
- # If +object+ is a \String,
15
- # calls JSON.parse with +object+ and +opts+ (see method #parse):
16
- # json = '[0, 1, null]'
17
- # JSON[json]# => [0, 1, nil]
18
- #
19
- # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate):
20
- # ruby = [0, 1, nil]
21
- # JSON[ruby] # => '[0,1,null]'
22
- def [](object, opts = {})
23
- if object.is_a?(String)
24
- return JSON.parse(object, opts)
25
- elsif object.respond_to?(:to_str)
26
- str = object.to_str
27
- if str.is_a?(String)
28
- return JSON.parse(object.to_str, opts)
29
- end
30
- end
31
-
32
- JSON.generate(object, opts)
33
- end
34
-
35
- # Returns the JSON parser class that is used by JSON. This is either
36
- # JSON::Ext::Parser or JSON::Pure::Parser:
37
- # JSON.parser # => JSON::Ext::Parser
38
- attr_reader :parser
39
-
40
- # Set the JSON parser class _parser_ to be used by JSON.
41
- def parser=(parser) # :nodoc:
42
- @parser = parser
43
- remove_const :Parser if const_defined?(:Parser, false)
44
- const_set :Parser, parser
45
- end
46
-
47
- # Return the constant located at _path_. The format of _path_ has to be
48
- # either ::A::B::C or A::B::C. In any case, A has to be located at the top
49
- # level (absolute namespace path?). If there doesn't exist a constant at
50
- # the given path, an ArgumentError is raised.
51
- def deep_const_get(path) # :nodoc:
52
- path.to_s.split(/::/).inject(Object) do |p, c|
53
- case
54
- when c.empty? then p
55
- when p.const_defined?(c, true) then p.const_get(c)
56
- else
57
- begin
58
- p.const_missing(c)
59
- rescue NameError => e
60
- raise ArgumentError, "can't get const #{path}: #{e}"
61
- end
62
- end
63
- end
64
- end
65
-
66
- # Set the module _generator_ to be used by JSON.
67
- def generator=(generator) # :nodoc:
68
- old, $VERBOSE = $VERBOSE, nil
69
- @generator = generator
70
- generator_methods = generator::GeneratorMethods
71
- for const in generator_methods.constants
72
- klass = deep_const_get(const)
73
- modul = generator_methods.const_get(const)
74
- klass.class_eval do
75
- instance_methods(false).each do |m|
76
- m.to_s == 'to_json' and remove_method m
77
- end
78
- include modul
79
- end
80
- end
81
- self.state = generator::State
82
- const_set :State, self.state
83
- const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby
84
- const_set :FAST_STATE_PROTOTYPE, create_fast_state
85
- const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state
86
- ensure
87
- $VERBOSE = old
88
- end
89
-
90
- def create_fast_state
91
- State.new(
92
- :indent => '',
93
- :space => '',
94
- :object_nl => "",
95
- :array_nl => "",
96
- :max_nesting => false
97
- )
98
- end
99
-
100
- def create_pretty_state
101
- State.new(
102
- :indent => ' ',
103
- :space => ' ',
104
- :object_nl => "\n",
105
- :array_nl => "\n"
106
- )
107
- end
108
-
109
- # Returns the JSON generator module that is used by JSON. This is
110
- # either JSON::Ext::Generator or JSON::Pure::Generator:
111
- # JSON.generator # => JSON::Ext::Generator
112
- attr_reader :generator
113
-
114
- # Sets or Returns the JSON generator state class that is used by JSON. This is
115
- # either JSON::Ext::Generator::State or JSON::Pure::Generator::State:
116
- # JSON.state # => JSON::Ext::Generator::State
117
- attr_accessor :state
118
- end
119
-
120
- # Sets create identifier, which is used to decide if the _json_create_
121
- # hook of a class should be called; initial value is +json_class+:
122
- # JSON.create_id # => 'json_class'
123
- def self.create_id=(new_value)
124
- Thread.current[:"JSON.create_id"] = new_value.dup.freeze
125
- end
126
-
127
- # Returns the current create identifier.
128
- # See also JSON.create_id=.
129
- def self.create_id
130
- Thread.current[:"JSON.create_id"] || 'json_class'
131
- end
132
-
133
- NaN = 0.0/0
134
-
135
- Infinity = 1.0/0
136
-
137
- MinusInfinity = -Infinity
138
-
139
- # The base exception for JSON errors.
140
- class JSONError < StandardError
141
- def self.wrap(exception)
142
- obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}")
143
- obj.set_backtrace exception.backtrace
144
- obj
145
- end
146
- end
147
-
148
- # This exception is raised if a parser error occurs.
149
- class ParserError < JSONError; end
150
-
151
- # This exception is raised if the nesting of parsed data structures is too
152
- # deep.
153
- class NestingError < ParserError; end
154
-
155
- # :stopdoc:
156
- class CircularDatastructure < NestingError; end
157
- # :startdoc:
158
-
159
- # This exception is raised if a generator or unparser error occurs.
160
- class GeneratorError < JSONError; end
161
- # For backwards compatibility
162
- UnparserError = GeneratorError # :nodoc:
163
-
164
- # This exception is raised if the required unicode support is missing on the
165
- # system. Usually this means that the iconv library is not installed.
166
- class MissingUnicodeSupport < JSONError; end
167
-
168
- module_function
169
-
170
- # :call-seq:
171
- # JSON.parse(source, opts) -> object
172
- #
173
- # Returns the Ruby objects created by parsing the given +source+.
174
- #
175
- # Argument +source+ contains the \String to be parsed.
176
- #
177
- # Argument +opts+, if given, contains a \Hash of options for the parsing.
178
- # See {Parsing Options}[#module-JSON-label-Parsing+Options].
179
- #
180
- # ---
181
- #
182
- # When +source+ is a \JSON array, returns a Ruby \Array:
183
- # source = '["foo", 1.0, true, false, null]'
184
- # ruby = JSON.parse(source)
185
- # ruby # => ["foo", 1.0, true, false, nil]
186
- # ruby.class # => Array
187
- #
188
- # When +source+ is a \JSON object, returns a Ruby \Hash:
189
- # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
190
- # ruby = JSON.parse(source)
191
- # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
192
- # ruby.class # => Hash
193
- #
194
- # For examples of parsing for all \JSON data types, see
195
- # {Parsing \JSON}[#module-JSON-label-Parsing+JSON].
196
- #
197
- # Parses nested JSON objects:
198
- # source = <<-EOT
199
- # {
200
- # "name": "Dave",
201
- # "age" :40,
202
- # "hats": [
203
- # "Cattleman's",
204
- # "Panama",
205
- # "Tophat"
206
- # ]
207
- # }
208
- # EOT
209
- # ruby = JSON.parse(source)
210
- # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
211
- #
212
- # ---
213
- #
214
- # Raises an exception if +source+ is not valid JSON:
215
- # # Raises JSON::ParserError (783: unexpected token at ''):
216
- # JSON.parse('')
217
- #
218
- def parse(source, opts = nil)
219
- if opts.nil?
220
- Parser.new(source).parse
221
- else
222
- Parser.new(source, opts).parse
223
- end
224
- end
225
-
226
- # :call-seq:
227
- # JSON.parse!(source, opts) -> object
228
- #
229
- # Calls
230
- # parse(source, opts)
231
- # with +source+ and possibly modified +opts+.
232
- #
233
- # Differences from JSON.parse:
234
- # - Option +max_nesting+, if not provided, defaults to +false+,
235
- # which disables checking for nesting depth.
236
- # - Option +allow_nan+, if not provided, defaults to +true+.
237
- def parse!(source, opts = {})
238
- opts = {
239
- :max_nesting => false,
240
- :allow_nan => true
241
- }.merge(opts)
242
- Parser.new(source, **(opts||{})).parse
243
- end
244
-
245
- # :call-seq:
246
- # JSON.load_file(path, opts={}) -> object
247
- #
248
- # Calls:
249
- # parse(File.read(path), opts)
250
- #
251
- # See method #parse.
252
- def load_file(filespec, opts = {})
253
- parse(File.read(filespec), opts)
254
- end
255
-
256
- # :call-seq:
257
- # JSON.load_file!(path, opts = {})
258
- #
259
- # Calls:
260
- # JSON.parse!(File.read(path, opts))
261
- #
262
- # See method #parse!
263
- def load_file!(filespec, opts = {})
264
- parse!(File.read(filespec), opts)
265
- end
266
-
267
- # :call-seq:
268
- # JSON.generate(obj, opts = nil) -> new_string
269
- #
270
- # Returns a \String containing the generated \JSON data.
271
- #
272
- # See also JSON.fast_generate, JSON.pretty_generate.
273
- #
274
- # Argument +obj+ is the Ruby object to be converted to \JSON.
275
- #
276
- # Argument +opts+, if given, contains a \Hash of options for the generation.
277
- # See {Generating Options}[#module-JSON-label-Generating+Options].
278
- #
279
- # ---
280
- #
281
- # When +obj+ is an \Array, returns a \String containing a \JSON array:
282
- # obj = ["foo", 1.0, true, false, nil]
283
- # json = JSON.generate(obj)
284
- # json # => '["foo",1.0,true,false,null]'
285
- #
286
- # When +obj+ is a \Hash, returns a \String containing a \JSON object:
287
- # obj = {foo: 0, bar: 's', baz: :bat}
288
- # json = JSON.generate(obj)
289
- # json # => '{"foo":0,"bar":"s","baz":"bat"}'
290
- #
291
- # For examples of generating from other Ruby objects, see
292
- # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects].
293
- #
294
- # ---
295
- #
296
- # Raises an exception if any formatting option is not a \String.
297
- #
298
- # Raises an exception if +obj+ contains circular references:
299
- # a = []; b = []; a.push(b); b.push(a)
300
- # # Raises JSON::NestingError (nesting of 100 is too deep):
301
- # JSON.generate(a)
302
- #
303
- def generate(obj, opts = nil)
304
- if State === opts
305
- state = opts
306
- else
307
- state = State.new(opts)
308
- end
309
- state.generate(obj)
310
- end
311
-
312
- # :stopdoc:
313
- # I want to deprecate these later, so I'll first be silent about them, and
314
- # later delete them.
315
- alias unparse generate
316
- module_function :unparse
317
- # :startdoc:
318
-
319
- # :call-seq:
320
- # JSON.fast_generate(obj, opts) -> new_string
321
- #
322
- # Arguments +obj+ and +opts+ here are the same as
323
- # arguments +obj+ and +opts+ in JSON.generate.
324
- #
325
- # By default, generates \JSON data without checking
326
- # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled).
327
- #
328
- # Raises an exception if +obj+ contains circular references:
329
- # a = []; b = []; a.push(b); b.push(a)
330
- # # Raises SystemStackError (stack level too deep):
331
- # JSON.fast_generate(a)
332
- def fast_generate(obj, opts = nil)
333
- if State === opts
334
- state = opts
335
- else
336
- state = JSON.create_fast_state.configure(opts)
337
- end
338
- state.generate(obj)
339
- end
340
-
341
- # :stopdoc:
342
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
343
- alias fast_unparse fast_generate
344
- module_function :fast_unparse
345
- # :startdoc:
346
-
347
- # :call-seq:
348
- # JSON.pretty_generate(obj, opts = nil) -> new_string
349
- #
350
- # Arguments +obj+ and +opts+ here are the same as
351
- # arguments +obj+ and +opts+ in JSON.generate.
352
- #
353
- # Default options are:
354
- # {
355
- # indent: ' ', # Two spaces
356
- # space: ' ', # One space
357
- # array_nl: "\n", # Newline
358
- # object_nl: "\n" # Newline
359
- # }
360
- #
361
- # Example:
362
- # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
363
- # json = JSON.pretty_generate(obj)
364
- # puts json
365
- # Output:
366
- # {
367
- # "foo": [
368
- # "bar",
369
- # "baz"
370
- # ],
371
- # "bat": {
372
- # "bam": 0,
373
- # "bad": 1
374
- # }
375
- # }
376
- #
377
- def pretty_generate(obj, opts = nil)
378
- if State === opts
379
- state, opts = opts, nil
380
- else
381
- state = JSON.create_pretty_state
382
- end
383
- if opts
384
- if opts.respond_to? :to_hash
385
- opts = opts.to_hash
386
- elsif opts.respond_to? :to_h
387
- opts = opts.to_h
388
- else
389
- raise TypeError, "can't convert #{opts.class} into Hash"
390
- end
391
- state.configure(opts)
392
- end
393
- state.generate(obj)
394
- end
395
-
396
- # :stopdoc:
397
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
398
- alias pretty_unparse pretty_generate
399
- module_function :pretty_unparse
400
- # :startdoc:
401
-
402
- class << self
403
- # Sets or returns default options for the JSON.load method.
404
- # Initially:
405
- # opts = JSON.load_default_options
406
- # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
407
- attr_accessor :load_default_options
408
- end
409
- self.load_default_options = {
410
- :max_nesting => false,
411
- :allow_nan => true,
412
- :allow_blank => true,
413
- :create_additions => true,
414
- }
415
-
416
- # :call-seq:
417
- # JSON.load(source, proc = nil, options = {}) -> object
418
- #
419
- # Returns the Ruby objects created by parsing the given +source+.
420
- #
421
- # - Argument +source+ must be, or be convertible to, a \String:
422
- # - If +source+ responds to instance method +to_str+,
423
- # <tt>source.to_str</tt> becomes the source.
424
- # - If +source+ responds to instance method +to_io+,
425
- # <tt>source.to_io.read</tt> becomes the source.
426
- # - If +source+ responds to instance method +read+,
427
- # <tt>source.read</tt> becomes the source.
428
- # - If both of the following are true, source becomes the \String <tt>'null'</tt>:
429
- # - Option +allow_blank+ specifies a truthy value.
430
- # - The source, as defined above, is +nil+ or the empty \String <tt>''</tt>.
431
- # - Otherwise, +source+ remains the source.
432
- # - Argument +proc+, if given, must be a \Proc that accepts one argument.
433
- # It will be called recursively with each result (depth-first order).
434
- # See details below.
435
- # BEWARE: This method is meant to serialise data from trusted user input,
436
- # like from your own database server or clients under your control, it could
437
- # be dangerous to allow untrusted users to pass JSON sources into it.
438
- # - Argument +opts+, if given, contains a \Hash of options for the parsing.
439
- # See {Parsing Options}[#module-JSON-label-Parsing+Options].
440
- # The default options can be changed via method JSON.load_default_options=.
441
- #
442
- # ---
443
- #
444
- # When no +proc+ is given, modifies +source+ as above and returns the result of
445
- # <tt>parse(source, opts)</tt>; see #parse.
446
- #
447
- # Source for following examples:
448
- # source = <<-EOT
449
- # {
450
- # "name": "Dave",
451
- # "age" :40,
452
- # "hats": [
453
- # "Cattleman's",
454
- # "Panama",
455
- # "Tophat"
456
- # ]
457
- # }
458
- # EOT
459
- #
460
- # Load a \String:
461
- # ruby = JSON.load(source)
462
- # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
463
- #
464
- # Load an \IO object:
465
- # require 'stringio'
466
- # object = JSON.load(StringIO.new(source))
467
- # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
468
- #
469
- # Load a \File object:
470
- # path = 't.json'
471
- # File.write(path, source)
472
- # File.open(path) do |file|
473
- # JSON.load(file)
474
- # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
475
- #
476
- # ---
477
- #
478
- # When +proc+ is given:
479
- # - Modifies +source+ as above.
480
- # - Gets the +result+ from calling <tt>parse(source, opts)</tt>.
481
- # - Recursively calls <tt>proc(result)</tt>.
482
- # - Returns the final result.
483
- #
484
- # Example:
485
- # require 'json'
486
- #
487
- # # Some classes for the example.
488
- # class Base
489
- # def initialize(attributes)
490
- # @attributes = attributes
491
- # end
492
- # end
493
- # class User < Base; end
494
- # class Account < Base; end
495
- # class Admin < Base; end
496
- # # The JSON source.
497
- # json = <<-EOF
498
- # {
499
- # "users": [
500
- # {"type": "User", "username": "jane", "email": "jane@example.com"},
501
- # {"type": "User", "username": "john", "email": "john@example.com"}
502
- # ],
503
- # "accounts": [
504
- # {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
505
- # {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
506
- # ],
507
- # "admins": {"type": "Admin", "password": "0wn3d"}
508
- # }
509
- # EOF
510
- # # Deserializer method.
511
- # def deserialize_obj(obj, safe_types = %w(User Account Admin))
512
- # type = obj.is_a?(Hash) && obj["type"]
513
- # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
514
- # end
515
- # # Call to JSON.load
516
- # ruby = JSON.load(json, proc {|obj|
517
- # case obj
518
- # when Hash
519
- # obj.each {|k, v| obj[k] = deserialize_obj v }
520
- # when Array
521
- # obj.map! {|v| deserialize_obj v }
522
- # end
523
- # })
524
- # pp ruby
525
- # Output:
526
- # {"users"=>
527
- # [#<User:0x00000000064c4c98
528
- # @attributes=
529
- # {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
530
- # #<User:0x00000000064c4bd0
531
- # @attributes=
532
- # {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
533
- # "accounts"=>
534
- # [{"account"=>
535
- # #<Account:0x00000000064c4928
536
- # @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
537
- # {"account"=>
538
- # #<Account:0x00000000064c4680
539
- # @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
540
- # "admins"=>
541
- # #<Admin:0x00000000064c41f8
542
- # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
543
- #
544
- def load(source, proc = nil, options = nil)
545
- opts = if options.nil?
546
- load_default_options
547
- else
548
- load_default_options.merge(options)
549
- end
550
-
551
- unless source.is_a?(String)
552
- if source.respond_to? :to_str
553
- source = source.to_str
554
- elsif source.respond_to? :to_io
555
- source = source.to_io.read
556
- elsif source.respond_to?(:read)
557
- source = source.read
558
- end
559
- end
560
-
561
- if opts[:allow_blank] && (source.nil? || source.empty?)
562
- source = 'null'
563
- end
564
- result = parse(source, opts)
565
- recurse_proc(result, &proc) if proc
566
- result
567
- end
568
-
569
- # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_
570
- def recurse_proc(result, &proc) # :nodoc:
571
- case result
572
- when Array
573
- result.each { |x| recurse_proc x, &proc }
574
- proc.call result
575
- when Hash
576
- result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
577
- proc.call result
578
- else
579
- proc.call result
580
- end
581
- end
582
-
583
- alias restore load
584
- module_function :restore
585
-
586
- class << self
587
- # Sets or returns the default options for the JSON.dump method.
588
- # Initially:
589
- # opts = JSON.dump_default_options
590
- # opts # => {:max_nesting=>false, :allow_nan=>true}
591
- attr_accessor :dump_default_options
592
- end
593
- self.dump_default_options = {
594
- :max_nesting => false,
595
- :allow_nan => true,
596
- }
597
-
598
- # :call-seq:
599
- # JSON.dump(obj, io = nil, limit = nil)
600
- #
601
- # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result.
602
- #
603
- # The default options can be changed via method JSON.dump_default_options.
604
- #
605
- # - Argument +io+, if given, should respond to method +write+;
606
- # the \JSON \String is written to +io+, and +io+ is returned.
607
- # If +io+ is not given, the \JSON \String is returned.
608
- # - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+.
609
- #
610
- # ---
611
- #
612
- # When argument +io+ is not given, returns the \JSON \String generated from +obj+:
613
- # obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
614
- # json = JSON.dump(obj)
615
- # json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}"
616
- #
617
- # When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+:
618
- # path = 't.json'
619
- # File.open(path, 'w') do |file|
620
- # JSON.dump(obj, file)
621
- # end # => #<File:t.json (closed)>
622
- # puts File.read(path)
623
- # Output:
624
- # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
625
- def dump(obj, anIO = nil, limit = nil, kwargs = nil)
626
- if kwargs.nil?
627
- if limit.nil?
628
- if anIO.is_a?(Hash)
629
- kwargs = anIO
630
- anIO = nil
631
- end
632
- elsif limit.is_a?(Hash)
633
- kwargs = limit
634
- limit = nil
635
- end
636
- end
637
-
638
- unless anIO.nil?
639
- if anIO.respond_to?(:to_io)
640
- anIO = anIO.to_io
641
- elsif limit.nil? && !anIO.respond_to?(:write)
642
- anIO, limit = nil, anIO
643
- end
644
- end
645
-
646
- opts = JSON.dump_default_options
647
- opts = opts.merge(:max_nesting => limit) if limit
648
- opts = merge_dump_options(opts, **kwargs) if kwargs
649
-
650
- result = begin
651
- generate(obj, opts)
652
- rescue JSON::NestingError
653
- raise ArgumentError, "exceed depth limit"
654
- end
655
-
656
- if anIO.nil?
657
- result
658
- else
659
- anIO.write result
660
- anIO
661
- end
662
- end
663
-
664
- # Encodes string using String.encode.
665
- def self.iconv(to, from, string)
666
- string.encode(to, from)
667
- end
668
-
669
- def merge_dump_options(opts, strict: NOT_SET)
670
- opts = opts.merge(strict: strict) if NOT_SET != strict
671
- opts
672
- end
673
-
674
- class << self
675
- private :merge_dump_options
676
- end
677
- end
678
-
679
- module ::Kernel
680
- private
681
-
682
- # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
683
- # one line.
684
- def j(*objs)
685
- objs.each do |obj|
686
- puts JSON::generate(obj, :allow_nan => true, :max_nesting => false)
687
- end
688
- nil
689
- end
690
-
691
- # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with
692
- # indentation and over many lines.
693
- def jj(*objs)
694
- objs.each do |obj|
695
- puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false)
696
- end
697
- nil
698
- end
699
-
700
- # If _object_ is string-like, parse the string and return the parsed result as
701
- # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data
702
- # structure object and return it.
703
- #
704
- # The _opts_ argument is passed through to generate/parse respectively. See
705
- # generate and parse for their documentation.
706
- def JSON(object, *args)
707
- if object.is_a?(String)
708
- return JSON.parse(object, args.first)
709
- elsif object.respond_to?(:to_str)
710
- str = object.to_str
711
- if str.is_a?(String)
712
- return JSON.parse(object.to_str, args.first)
713
- end
714
- end
715
-
716
- JSON.generate(object, args.first)
717
- end
718
- end
719
-
720
- # Extends any Class to include _json_creatable?_ method.
721
- class ::Class
722
- # Returns true if this class can be used to create an instance
723
- # from a serialised JSON string. The class has to implement a class
724
- # method _json_create_ that expects a hash as first parameter. The hash
725
- # should include the required data.
726
- def json_creatable?
727
- respond_to?(:json_create)
728
- end
729
- end