oj 2.5.5 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +74 -51
- data/ext/oj/dump.c +2 -14
- data/ext/oj/oj.c +8 -0
- data/ext/oj/oj.h +1 -0
- data/lib/oj/version.rb +1 -1
- data/test/test_compat.rb +2 -2
- data/test/test_mimic.rb +2 -2
- data/test/tests.rb +9 -5
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88d1b989da1bbd42c7fa90ba96baa9c71f289631
|
4
|
+
data.tar.gz: 2d1643092b53fbf33db538856179f7385516346e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6433a3aa13a1afdabda2e44c732cc85989a38772702edf5ca70a984e9dbdc275f7a255cb405897e8b6898aced26490f11c17b55413638dd885bba2c9a7ed8a54
|
7
|
+
data.tar.gz: 79540125a8c5a1553622f786e5aee3a12c8e256060f545a87ae0d9bb5896ab7dc0e5bb4bcdc1f72d6a354d35c5a536adb8cde20bc11a128464405460b8e8a112
|
data/README.md
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
A fast JSON parser and Object marshaller as a Ruby gem.
|
3
3
|
|
4
4
|
## Installation
|
5
|
-
|
5
|
+
```
|
6
|
+
gem install oj
|
7
|
+
```
|
8
|
+
or in Bundler:
|
9
|
+
```
|
10
|
+
gem 'oj'
|
11
|
+
```
|
6
12
|
|
7
13
|
## Documentation
|
8
14
|
|
@@ -20,80 +26,82 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
|
|
20
26
|
|
21
27
|
[![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
|
22
28
|
|
23
|
-
### Current Release 2.
|
24
|
-
|
25
|
-
- Worked around the Rubinius failure to load bigdecimal from a require within
|
26
|
-
the C code.
|
27
|
-
|
28
|
-
### Current Release 2.5.4
|
29
|
+
### Current Release 2.6.0
|
29
30
|
|
30
|
-
-
|
31
|
+
- Added the `:use_to_json` option for Oj.dump(). If this option is set to false
|
32
|
+
the `to_json()` method on objects will not be calledwhen dumping. This is the
|
33
|
+
default behavior. The reason behind the option and change is to better
|
34
|
+
support Rails and ActiveSupport. Previous works arounds have been removed.
|
31
35
|
|
32
36
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
33
37
|
|
34
38
|
## Description
|
35
39
|
|
36
|
-
Optimized JSON (Oj), as the name implies was written to provide speed optimized
|
37
|
-
JSON handling. It was designed as a faster alternative to Yajl and other
|
38
|
-
common Ruby JSON parsers. So far
|
39
|
-
than any other Ruby JSON parser and 3 or more times faster
|
40
|
+
Optimized JSON (Oj), as the name implies, was written to provide speed optimized
|
41
|
+
JSON handling. It was designed as a faster alternative to Yajl and other
|
42
|
+
common Ruby JSON parsers. So far it has achieved that, and is about 2 times faster
|
43
|
+
than any other Ruby JSON parser, and 3 or more times faster at serializing JSON.
|
40
44
|
|
41
|
-
Oj has several dump or serialization modes which control how
|
42
|
-
converted to JSON. These modes are set with the
|
43
|
-
default options or as one of the options to the dump
|
44
|
-
is the
|
45
|
+
Oj has several `dump` or serialization modes which control how Ruby `Object`s are
|
46
|
+
converted to JSON. These modes are set with the `:mode` option in either the
|
47
|
+
default options or as one of the options to the `dump` method. The default mode
|
48
|
+
is the `:object` mode.
|
45
49
|
|
46
|
-
-
|
47
|
-
other Object will raise
|
50
|
+
- `:strict` mode will only allow the 7 basic JSON types to be serialized. Any
|
51
|
+
other `Object` will raise an `Exception`.
|
48
52
|
|
49
|
-
-
|
53
|
+
- `:null` mode replaces any `Object` that is not one of the JSON types with a JSON `null`.
|
50
54
|
|
51
|
-
-
|
52
|
-
Ruby Object's variable names without the '@' character. This is the highest
|
55
|
+
- `:object` mode will dump any `Object` as a JSON `Object` with keys that match the
|
56
|
+
Ruby `Object`'s variable names without the '@' prefix character. This is the highest
|
53
57
|
performance mode.
|
54
58
|
|
55
|
-
-
|
56
|
-
Object but will check to see if the Object implements
|
57
|
-
method. If either exists that method is used for serializing the Object
|
58
|
-
|
59
|
-
|
60
|
-
methods
|
59
|
+
- `:compat` mode attempts to be compatible with other systems. It will serialize any
|
60
|
+
`Object`, but will check to see if the `Object` implements an `as_hash` or `to_json`
|
61
|
+
method. If either exists, that method is used for serializing the `Object`.
|
62
|
+
Since `as_json` is more flexible and produces more consistent output, it is
|
63
|
+
preferred over the `to_json` method. If neither the `to_json` or `to_hash`
|
64
|
+
methods exists, then the Oj internal `Object` variable encoding is used.
|
61
65
|
|
62
|
-
|
66
|
+
|
67
|
+
## Compatibility
|
68
|
+
|
69
|
+
### Ruby
|
70
|
+
Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.1 and RBX. Support for
|
63
71
|
JRuby has been removed as JRuby no longer supports C extensions and there are
|
64
72
|
bugs in the older versions that are not being fixed.
|
65
73
|
|
66
|
-
|
67
|
-
[multi_json](https://github.com/intridea/multi_json)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
74
|
+
### Rails
|
75
|
+
Although up until 4.1 Rails uses [multi_json](https://github.com/intridea/multi_json), an [issue in Rails](https://github.com/rails/rails/issues/9212) causes ActiveSupport to fail to make use Oj for JSON handling.
|
76
|
+
There is a
|
77
|
+
[gem to patch this](https://github.com/GoodLife/rails-patch-json-encode) for
|
78
|
+
Rails 3.2 and 4.0. As of the Oj 2.6.0 release the default behavior is to not use
|
79
|
+
the `to_json()` method unless the `:use_to_json` option is set. This provides
|
80
|
+
another work around to the rails older and newer behavior.
|
72
81
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
parsing.
|
82
|
+
In version Rails 4.1, multi_json has been removed, and this patch is unnecessary and will no longer work.
|
83
|
+
Instead, use the `oj_mimic_json` [gem](https://github.com/ohler55/oj_mimic_json) along with `oj` in your `Gemfile` to have Oj mimic the JSON gem and be used in its place by `ActiveSupport` JSON handling:
|
84
|
+
```
|
85
|
+
gem 'oj'
|
86
|
+
gem 'oj_mimic_json'
|
87
|
+
```
|
80
88
|
|
81
89
|
## Proper Use
|
82
90
|
|
83
|
-
Two settings in Oj are useful for parsing but do expose a vunerability if used from an untrusted source.
|
84
|
-
keys can
|
85
|
-
defining classes
|
86
|
-
feature during development and from trusted sources but it
|
87
|
-
mode and auto defined is used with an untrusted source. The Oj.strict_load() method sets uses the most strict and safest
|
88
|
-
options. It should be used by developers who find it difficult to understand the options available in Oj.
|
91
|
+
Two settings in Oj are useful for parsing but do expose a vunerability if used from an untrusted source. Symbolized
|
92
|
+
keys can cause memory to be filled since Ruby does not garbage collect Symbols. The same is true for auto
|
93
|
+
defining classes; memory will also be exhausted if too many classes are automatically defined. Auto defining is a useful
|
94
|
+
feature during development and from trusted sources but it allows too many classes to be created in the object load
|
95
|
+
mode and auto defined is used with an untrusted source. The `Oj.strict_load()` method sets and uses the most strict and safest options. It should be used by developers who find it difficult to understand the options available in Oj.
|
89
96
|
|
90
97
|
The options in Oj are designed to provide flexibility to the developer. This flexibility allows Objects to be serialized
|
91
98
|
and deserialized. No methods are ever called on these created Objects but that does not stop the developer from calling
|
92
|
-
methods on
|
93
|
-
from a user and evaluating it is never a good idea from an unsecure source. The same is true for Object attributes as
|
94
|
-
they are not more than
|
99
|
+
methods on them. As in any system, check your inputs before working with them. Taking an arbitrary `String`
|
100
|
+
from a user and evaluating it is never a good idea from an unsecure source. The same is true for `Object` attributes as
|
101
|
+
they are not more than `String`s. Always check inputs from untrusted sources.
|
95
102
|
|
96
|
-
|
103
|
+
|
104
|
+
## Simple JSON Writing and Parsing Example
|
97
105
|
|
98
106
|
```ruby
|
99
107
|
require 'oj'
|
@@ -115,6 +123,21 @@ puts "Same? #{h == h2}"
|
|
115
123
|
# true
|
116
124
|
```
|
117
125
|
|
126
|
+
## Alternative JSON Processing APIs
|
127
|
+
|
128
|
+
Oj offers a few alternative APIs for processing JSON. The fastest one is the `Oj::Doc` API. The `Oj::Doc` API takes a
|
129
|
+
completely different approach by opening a JSON document and providing calls to navigate around the JSON while it is
|
130
|
+
open. With this approach, JSON access can be well over 20 times faster than conventional JSON parsing.
|
131
|
+
|
132
|
+
The `Oj::Saj` and `Oj::ScHandler` APIs are callback parsers that
|
133
|
+
walk the JSON document depth first and makes callbacks for each element.
|
134
|
+
Both callback parser are useful when only portions of the JSON are of
|
135
|
+
interest. Performance up to 20 times faster than conventional JSON is
|
136
|
+
possible. The API is simple to use but does require a different approach than
|
137
|
+
the conventional parse followed by access approach used by conventional JSON
|
138
|
+
parsing.
|
139
|
+
|
140
|
+
|
118
141
|
# Links
|
119
142
|
|
120
143
|
## Performance Comparisons
|
data/ext/oj/dump.c
CHANGED
@@ -107,11 +107,6 @@ static void dump_leaf_float(Leaf leaf, Out out);
|
|
107
107
|
static void dump_leaf_array(Leaf leaf, int depth, Out out);
|
108
108
|
static void dump_leaf_hash(Leaf leaf, int depth, Out out);
|
109
109
|
|
110
|
-
// These are used to detect rails re-call of Oj.dump() inside the to_json()
|
111
|
-
// method. It is not thread safe.
|
112
|
-
static VALUE last_obj = Qundef;
|
113
|
-
static int oj_rails_hack = -1;
|
114
|
-
|
115
110
|
static const char hex_chars[17] = "0123456789abcdef";
|
116
111
|
|
117
112
|
static char hibit_friendly_chars[256] = "\
|
@@ -1156,14 +1151,12 @@ dump_data_comp(VALUE obj, int depth, Out out) {
|
|
1156
1151
|
dump_hash(h, depth, out->opts->mode, out);
|
1157
1152
|
} else if (rb_respond_to(obj, oj_as_json_id) && obj != (o2 = rb_funcall(obj, oj_as_json_id, 0))) {
|
1158
1153
|
dump_val(o2, depth, out);
|
1159
|
-
} else if (rb_respond_to(obj, oj_to_json_id)
|
1154
|
+
} else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
|
1160
1155
|
volatile VALUE rs;
|
1161
1156
|
const char *s;
|
1162
1157
|
int len;
|
1163
1158
|
|
1164
|
-
last_obj = obj;
|
1165
1159
|
rs = rb_funcall(obj, oj_to_json_id, 0);
|
1166
|
-
last_obj = Qundef;
|
1167
1160
|
s = rb_string_value_ptr((VALUE*)&rs);
|
1168
1161
|
len = (int)RSTRING_LEN(rs);
|
1169
1162
|
|
@@ -1248,14 +1241,12 @@ dump_obj_comp(VALUE obj, int depth, Out out) {
|
|
1248
1241
|
dump_hash(h, depth, out->opts->mode, out);
|
1249
1242
|
} else if (rb_respond_to(obj, oj_as_json_id)) {
|
1250
1243
|
dump_val(rb_funcall(obj, oj_as_json_id, 0), depth, out);
|
1251
|
-
} else if (rb_respond_to(obj, oj_to_json_id)
|
1244
|
+
} else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
|
1252
1245
|
volatile VALUE rs;
|
1253
1246
|
const char *s;
|
1254
1247
|
int len;
|
1255
1248
|
|
1256
|
-
last_obj = obj;
|
1257
1249
|
rs = rb_funcall(obj, oj_to_json_id, 0);
|
1258
|
-
last_obj = Qundef;
|
1259
1250
|
s = rb_string_value_ptr((VALUE*)&rs);
|
1260
1251
|
len = (int)RSTRING_LEN(rs);
|
1261
1252
|
|
@@ -1731,9 +1722,6 @@ oj_dump_obj_to_json(VALUE obj, Options copts, Out out) {
|
|
1731
1722
|
oj_cache8_new(&out->circ_cache);
|
1732
1723
|
}
|
1733
1724
|
out->indent = copts->indent;
|
1734
|
-
if (0 > oj_rails_hack) {
|
1735
|
-
oj_rails_hack = (rb_const_defined_at(rb_cObject, rb_intern("ActiveSupport")));
|
1736
|
-
}
|
1737
1725
|
dump_val(obj, 0, out);
|
1738
1726
|
if (Yes == copts->circular) {
|
1739
1727
|
oj_cache8_delete(out->circ_cache);
|
data/ext/oj/oj.c
CHANGED
@@ -118,6 +118,7 @@ static VALUE strict_sym;
|
|
118
118
|
static VALUE symbol_keys_sym;
|
119
119
|
static VALUE time_format_sym;
|
120
120
|
static VALUE unix_sym;
|
121
|
+
static VALUE use_to_json_sym;
|
121
122
|
static VALUE xmlschema_sym;
|
122
123
|
static VALUE xss_safe_sym;
|
123
124
|
|
@@ -154,6 +155,7 @@ struct _Options oj_default_options = {
|
|
154
155
|
UnixTime, // time_format
|
155
156
|
Yes, // bigdec_as_num
|
156
157
|
AutoDec, // bigdec_load
|
158
|
+
No, // to_json
|
157
159
|
json_class, // create_id
|
158
160
|
10, // create_id_len
|
159
161
|
9, // sec_prec
|
@@ -178,6 +180,7 @@ static VALUE define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
178
180
|
* - bigdecimal_load: [:bigdecimal|:float|:auto] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
179
181
|
* - create_id: [String|nil] create id for json compatible object encoding, default is 'json_create'
|
180
182
|
* - second_precision: [Fixnum|nil] number of digits after the decimal when dumping the seconds portion of time
|
183
|
+
* - use_to_json: [true|false|nil] call to_json() methods on dump, default is false
|
181
184
|
* - allow_gc: [true|false|nil] allow or prohibit GC during parsing, default is true (allow)
|
182
185
|
* @return [Hash] all current option settings.
|
183
186
|
*/
|
@@ -192,6 +195,7 @@ get_def_opts(VALUE self) {
|
|
192
195
|
rb_hash_aset(opts, auto_define_sym, (Yes == oj_default_options.auto_define) ? Qtrue : ((No == oj_default_options.auto_define) ? Qfalse : Qnil));
|
193
196
|
rb_hash_aset(opts, symbol_keys_sym, (Yes == oj_default_options.sym_key) ? Qtrue : ((No == oj_default_options.sym_key) ? Qfalse : Qnil));
|
194
197
|
rb_hash_aset(opts, bigdecimal_as_decimal_sym, (Yes == oj_default_options.bigdec_as_num) ? Qtrue : ((No == oj_default_options.bigdec_as_num) ? Qfalse : Qnil));
|
198
|
+
rb_hash_aset(opts, use_to_json_sym, (Yes == oj_default_options.to_json) ? Qtrue : ((No == oj_default_options.to_json) ? Qfalse : Qnil));
|
195
199
|
rb_hash_aset(opts, allow_gc_sym, (Yes == oj_default_options.allow_gc) ? Qtrue : ((No == oj_default_options.allow_gc) ? Qfalse : Qnil));
|
196
200
|
switch (oj_default_options.mode) {
|
197
201
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
@@ -251,6 +255,7 @@ get_def_opts(VALUE self) {
|
|
251
255
|
* :ruby Time.to_s formatted String
|
252
256
|
* @param [String|nil] :create_id create id for json compatible object encoding
|
253
257
|
* @param [Fixnum|nil] :second_precision number of digits after the decimal when dumping the seconds portion of time
|
258
|
+
* @param [true|false|nil] :use_to_json call to_json() methods on dump, default is false
|
254
259
|
* @param [true|false|nil] :allow_gc allow or prohibit GC during parsing, default is true (allow)
|
255
260
|
* @return [nil]
|
256
261
|
*/
|
@@ -262,6 +267,7 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
262
267
|
{ symbol_keys_sym, &oj_default_options.sym_key },
|
263
268
|
{ class_cache_sym, &oj_default_options.class_cache },
|
264
269
|
{ bigdecimal_as_decimal_sym, &oj_default_options.bigdec_as_num },
|
270
|
+
{ use_to_json_sym, &oj_default_options.to_json },
|
265
271
|
{ allow_gc_sym, &oj_default_options.allow_gc },
|
266
272
|
{ Qnil, 0 }
|
267
273
|
};
|
@@ -392,6 +398,7 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
392
398
|
{ symbol_keys_sym, &copts->sym_key },
|
393
399
|
{ class_cache_sym, &copts->class_cache },
|
394
400
|
{ bigdecimal_as_decimal_sym, &copts->bigdec_as_num },
|
401
|
+
{ use_to_json_sym, &copts->to_json },
|
395
402
|
{ allow_gc_sym, &copts->allow_gc },
|
396
403
|
{ Qnil, 0 }
|
397
404
|
};
|
@@ -1821,6 +1828,7 @@ void Init_oj() {
|
|
1821
1828
|
symbol_keys_sym = ID2SYM(rb_intern("symbol_keys")); rb_gc_register_address(&symbol_keys_sym);
|
1822
1829
|
time_format_sym = ID2SYM(rb_intern("time_format")); rb_gc_register_address(&time_format_sym);
|
1823
1830
|
unix_sym = ID2SYM(rb_intern("unix")); rb_gc_register_address(&unix_sym);
|
1831
|
+
use_to_json_sym = ID2SYM(rb_intern("use_to_json")); rb_gc_register_address(&use_to_json_sym);
|
1824
1832
|
xmlschema_sym = ID2SYM(rb_intern("xmlschema")); rb_gc_register_address(&xmlschema_sym);
|
1825
1833
|
xss_safe_sym = ID2SYM(rb_intern("xss_safe")); rb_gc_register_address(&xss_safe_sym);
|
1826
1834
|
|
data/ext/oj/oj.h
CHANGED
@@ -135,6 +135,7 @@ typedef struct _Options {
|
|
135
135
|
char time_format; // TimeFormat
|
136
136
|
char bigdec_as_num; // YesNo
|
137
137
|
char bigdec_load; // BigLoad
|
138
|
+
char to_json; // YesNo
|
138
139
|
const char *create_id; // 0 or string
|
139
140
|
size_t create_id_len; // length of create_id
|
140
141
|
int sec_prec; // second precision when dumping time
|
data/lib/oj/version.rb
CHANGED
data/test/test_compat.rb
CHANGED
data/test/test_mimic.rb
CHANGED
data/test/tests.rb
CHANGED
@@ -134,6 +134,7 @@ class Juice < ::Test::Unit::TestCase
|
|
134
134
|
:time_format=>:unix,
|
135
135
|
:bigdecimal_as_decimal=>true,
|
136
136
|
:bigdecimal_load=>:auto,
|
137
|
+
:use_to_json=>false,
|
137
138
|
:allow_gc=>true,
|
138
139
|
:create_id=>'json_class'}, opts)
|
139
140
|
end
|
@@ -151,6 +152,7 @@ class Juice < ::Test::Unit::TestCase
|
|
151
152
|
:time_format=>:unix,
|
152
153
|
:bigdecimal_as_decimal=>true,
|
153
154
|
:bigdecimal_load=>:auto,
|
155
|
+
:use_to_json=>true,
|
154
156
|
:allow_gc=>true,
|
155
157
|
:create_id=>'json_class'}
|
156
158
|
o2 = {
|
@@ -165,6 +167,7 @@ class Juice < ::Test::Unit::TestCase
|
|
165
167
|
:time_format=>:ruby,
|
166
168
|
:bigdecimal_as_decimal=>false,
|
167
169
|
:bigdecimal_load=>:bigdecimal,
|
170
|
+
:use_to_json=>false,
|
168
171
|
:allow_gc=>false,
|
169
172
|
:create_id=>nil}
|
170
173
|
o3 = { :indent => 4 }
|
@@ -561,12 +564,13 @@ class Juice < ::Test::Unit::TestCase
|
|
561
564
|
assert_equal('null', json)
|
562
565
|
end
|
563
566
|
def test_json_object_compat
|
564
|
-
Oj.default_options = { :mode => :compat }
|
567
|
+
Oj.default_options = { :mode => :compat, :use_to_json => true }
|
565
568
|
obj = Jeez.new(true, 58)
|
566
569
|
json = Oj.dump(obj, :indent => 2)
|
567
570
|
assert(%{{"json_class":"Jeez","x":true,"y":58}} == json ||
|
568
571
|
%{{"json_class":"Jeez","y":58,"x":true}} == json)
|
569
572
|
dump_and_load(obj, false)
|
573
|
+
Oj.default_options = { :mode => :compat, :use_to_json => false }
|
570
574
|
end
|
571
575
|
def test_json_object_create_id
|
572
576
|
Oj.default_options = { :mode => :compat, :create_id => 'kson_class' }
|
@@ -862,15 +866,15 @@ class Juice < ::Test::Unit::TestCase
|
|
862
866
|
assert_equal(Float, bg.class)
|
863
867
|
assert_equal(orig.to_f, bg)
|
864
868
|
end
|
865
|
-
def
|
869
|
+
def test_bigdecimal_compat_as_json
|
866
870
|
orig = BigDecimal.new('80.51')
|
867
|
-
BigDecimal.send(:define_method, :
|
868
|
-
%{
|
871
|
+
BigDecimal.send(:define_method, :as_json) do
|
872
|
+
%{this is big}
|
869
873
|
end
|
870
874
|
json = Oj.dump(orig, :mode => :compat)
|
871
875
|
bg = Oj.load(json, :mode => :compat)
|
872
876
|
assert_equal("this is big", bg)
|
873
|
-
BigDecimal.send(:remove_method, :
|
877
|
+
BigDecimal.send(:remove_method, :as_json) # cleanup
|
874
878
|
end
|
875
879
|
def test_bigdecimal_object
|
876
880
|
mode = Oj.default_options[:mode]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'The fastest JSON parser and object serializer. '
|
14
14
|
email: peter@ohler.com
|
@@ -123,9 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project: oj
|
126
|
-
rubygems_version: 2.2.
|
126
|
+
rubygems_version: 2.2.2
|
127
127
|
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: A fast JSON parser and serializer.
|
130
130
|
test_files: []
|
131
|
-
has_rdoc: true
|