insensitive_hash 0.2.1 → 0.2.2
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/CHANGELOG.markdown +6 -0
- data/README.markdown +20 -3
- data/lib/insensitive_hash.rb +6 -2
- data/lib/insensitive_hash/insensitive_hash.rb +64 -19
- data/lib/insensitive_hash/version.rb +1 -1
- data/test/test_insensitive_hash.rb +256 -3
- metadata +4 -4
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### 0.2.2 / 2012/02/13
|
2
|
+
* :underscore option added
|
3
|
+
* `Insensitive::KeyClashError` added for safer operations
|
4
|
+
* Bug fix: Preserve default/default_proc on merge/replace/insensitive
|
5
|
+
* Subtle behavioral change in `Insensitive#replace` when called with an ordinary Hash
|
6
|
+
|
1
7
|
### 0.2.1 / 2012/02/10
|
2
8
|
* Bug fix: Insensitive `fetch`
|
3
9
|
|
data/README.markdown
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
|
1
|
+
insensitive_hash
|
2
|
+
================
|
2
3
|
Hash with case-insensitive, Symbol/String-indifferent key access.
|
3
4
|
|
4
|
-
|
5
|
+
Installation
|
6
|
+
------------
|
5
7
|
```
|
6
8
|
gem install insensitive_hash
|
7
9
|
```
|
8
10
|
|
9
|
-
|
11
|
+
Examples
|
12
|
+
--------
|
10
13
|
|
11
14
|
### Instantiation
|
12
15
|
```ruby
|
@@ -69,6 +72,20 @@ db['Development']['ADAPTER']
|
|
69
72
|
db[:production][:adapter]
|
70
73
|
```
|
71
74
|
|
75
|
+
### Replacing spaces in String keys to underscores
|
76
|
+
```ruby
|
77
|
+
h = { 'A key with spaces' => true }
|
78
|
+
|
79
|
+
ih = h.insensitive :underscore => true
|
80
|
+
ih[:a_key_with_spaces] # true
|
81
|
+
|
82
|
+
# Or,
|
83
|
+
ih = InsensitiveHash[ h ]
|
84
|
+
ih.underscore = true
|
85
|
+
ih.underscore? # true
|
86
|
+
ih[:a_key_with_spaces] # true
|
87
|
+
```
|
88
|
+
|
72
89
|
## Contributing to insensitive_hash
|
73
90
|
|
74
91
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
data/lib/insensitive_hash.rb
CHANGED
@@ -2,8 +2,12 @@ require 'insensitive_hash/version'
|
|
2
2
|
require 'insensitive_hash/insensitive_hash'
|
3
3
|
|
4
4
|
class Hash
|
5
|
-
|
6
|
-
|
5
|
+
# @return [InsensitiveHash]
|
6
|
+
def insensitive options = {}
|
7
|
+
InsensitiveHash.new.tap do |ih|
|
8
|
+
ih.replace self
|
9
|
+
ih.underscore = options[:underscore] if options.has_key?(:underscore)
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
9
13
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class InsensitiveHash < Hash
|
2
|
-
|
2
|
+
class KeyClashError < Exception
|
3
|
+
end
|
3
4
|
|
4
5
|
def initialize default = nil, &block
|
5
6
|
if block_given?
|
@@ -8,7 +9,31 @@ class InsensitiveHash < Hash
|
|
8
9
|
super
|
9
10
|
end
|
10
11
|
|
11
|
-
@key_map
|
12
|
+
@key_map = {}
|
13
|
+
@underscore = false
|
14
|
+
end
|
15
|
+
|
16
|
+
# Sets whether to replace spaces in String keys to underscores
|
17
|
+
# @param [Boolean] us
|
18
|
+
# @return [Boolean]
|
19
|
+
def underscore= us
|
20
|
+
raise ArgumentError.new("Not true or false") unless [true, false].include?(us)
|
21
|
+
|
22
|
+
# Check key clash
|
23
|
+
detect_clash self, us
|
24
|
+
|
25
|
+
@underscore = us
|
26
|
+
@key_map = {}
|
27
|
+
self.keys.each do |k|
|
28
|
+
self[k] = self.delete(k)
|
29
|
+
end
|
30
|
+
|
31
|
+
us
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Boolean] Whether to replace spaces in String keys to underscores
|
35
|
+
def underscore?
|
36
|
+
@underscore
|
12
37
|
end
|
13
38
|
|
14
39
|
# Returns a normal, sensitive Hash
|
@@ -36,17 +61,15 @@ class InsensitiveHash < Hash
|
|
36
61
|
end
|
37
62
|
|
38
63
|
def []= key, value
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
@key_map[encode key] = key
|
45
|
-
super(lookup_key(key), InsensitiveHash.wrap(value))
|
64
|
+
delete key
|
65
|
+
ekey = encode key, @underscore
|
66
|
+
@key_map[ekey] = key
|
67
|
+
super key, wrap(value, underscore?)
|
46
68
|
end
|
47
69
|
alias store []=
|
48
70
|
|
49
71
|
def merge! other_hash
|
72
|
+
detect_clash other_hash, underscore?
|
50
73
|
other_hash.each do |key, value|
|
51
74
|
self[key] = value
|
52
75
|
end
|
@@ -55,7 +78,8 @@ class InsensitiveHash < Hash
|
|
55
78
|
alias update! merge!
|
56
79
|
|
57
80
|
def merge other_hash
|
58
|
-
InsensitiveHash
|
81
|
+
InsensitiveHash.new.tap do |ih|
|
82
|
+
ih.replace self
|
59
83
|
ih.merge! other_hash
|
60
84
|
end
|
61
85
|
end
|
@@ -71,6 +95,16 @@ class InsensitiveHash < Hash
|
|
71
95
|
end
|
72
96
|
|
73
97
|
def replace other
|
98
|
+
# TODO
|
99
|
+
# What is the correct behavior of replace when the other hash is not an InsensitiveHash?
|
100
|
+
# underscore property precedence: other => self (FIXME)
|
101
|
+
us = other.respond_to?(:underscore?) ? other.underscore? : self.underscore?
|
102
|
+
detect_clash other, us
|
103
|
+
|
104
|
+
self.default = other.default
|
105
|
+
self.default_proc = other.default_proc if other.default_proc
|
106
|
+
self.underscore = us
|
107
|
+
|
74
108
|
clear
|
75
109
|
other.each do |k, v|
|
76
110
|
self[k] = v
|
@@ -93,19 +127,21 @@ class InsensitiveHash < Hash
|
|
93
127
|
end
|
94
128
|
|
95
129
|
private
|
96
|
-
def
|
130
|
+
def wrap value, us
|
97
131
|
case value
|
132
|
+
when InsensitiveHash
|
133
|
+
value.tap { |ih| ih.underscore = us || ih.underscore? }
|
98
134
|
when Hash
|
99
|
-
value.
|
135
|
+
InsensitiveHash[value].tap { |ih| ih.underscore = us }
|
100
136
|
when Array
|
101
|
-
value.map { |v|
|
137
|
+
value.map { |v| wrap v, us }
|
102
138
|
else
|
103
139
|
value
|
104
140
|
end
|
105
141
|
end
|
106
142
|
|
107
143
|
def lookup_key key, delete = false
|
108
|
-
ekey = encode key
|
144
|
+
ekey = encode key, @underscore
|
109
145
|
if @key_map.has_key?(ekey)
|
110
146
|
delete ? @key_map.delete(ekey) : @key_map[ekey]
|
111
147
|
else
|
@@ -113,15 +149,24 @@ private
|
|
113
149
|
end
|
114
150
|
end
|
115
151
|
|
116
|
-
def encode key
|
152
|
+
def encode key, us
|
117
153
|
case key
|
118
|
-
when String
|
119
|
-
key.downcase
|
120
|
-
|
121
|
-
|
154
|
+
when String, Symbol
|
155
|
+
key = key.to_s.downcase
|
156
|
+
if us
|
157
|
+
key.gsub(' ', '_')
|
158
|
+
else
|
159
|
+
key
|
160
|
+
end
|
122
161
|
else
|
123
162
|
key
|
124
163
|
end
|
125
164
|
end
|
165
|
+
|
166
|
+
def detect_clash hash, us
|
167
|
+
hash.keys.map { |k| encode k, us }.tap { |ekeys|
|
168
|
+
raise KeyClashError.new("Key clash detected") if ekeys != ekeys.uniq
|
169
|
+
}
|
170
|
+
end
|
126
171
|
end
|
127
172
|
|
@@ -73,6 +73,60 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
# InsensitiveHash#insensitive
|
78
|
+
ihash1 = hash.insensitive
|
79
|
+
ihash1.default = :default
|
80
|
+
ihash1.underscore = true
|
81
|
+
ihash2 = ihash1.insensitive.insensitive.insensitive
|
82
|
+
|
83
|
+
assert_equal InsensitiveHash, ihash2.class
|
84
|
+
assert_equal :default, ihash2.default
|
85
|
+
assert_equal true, ihash2.underscore?
|
86
|
+
|
87
|
+
# Preserving default
|
88
|
+
[:default, nil].each do |d|
|
89
|
+
hash.default = d
|
90
|
+
assert_equal d, hash.insensitive.insensitive.insensitive[:anything]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Preserving default_proc
|
94
|
+
hash2 = {}
|
95
|
+
hash2.replace hash
|
96
|
+
hash2.default_proc = proc { |h, k| h[k] = :default }
|
97
|
+
|
98
|
+
ihash2 = hash2.insensitive.insensitive.insensitive
|
99
|
+
assert !ihash2.has_key?(:anything)
|
100
|
+
assert_equal :default, ihash2[:anything]
|
101
|
+
assert ihash2.has_key?(:anything)
|
102
|
+
|
103
|
+
# FIXME: test insensitive call with encoder
|
104
|
+
h = InsensitiveHash[{'Key with spaces' => 1}]
|
105
|
+
h2 = h.insensitive :underscore => true
|
106
|
+
h3 = h.insensitive :underscore => false
|
107
|
+
assert_raise(ArgumentError) { h.insensitive :underscore => :wat }
|
108
|
+
|
109
|
+
assert_equal 1, h['key with spaces']
|
110
|
+
assert_nil h[:key_with_spaces]
|
111
|
+
assert_equal 1, h3['key with spaces']
|
112
|
+
assert_nil h3[:key_with_spaces]
|
113
|
+
assert_equal 1, h2[:KEY_WITH_SPACES]
|
114
|
+
assert_equal 1, h2[:Key_with_spaces]
|
115
|
+
|
116
|
+
assert_equal ['Key with spaces'], h.keys
|
117
|
+
assert_equal ['Key with spaces'], h2.keys
|
118
|
+
assert_equal ['Key with spaces'], h3.keys
|
119
|
+
|
120
|
+
h = { 'A key with spaces' => true }
|
121
|
+
ih = h.insensitive :underscore => true
|
122
|
+
assert ih[:a_key_with_spaces]
|
123
|
+
assert ih.underscore?
|
124
|
+
|
125
|
+
# FIXME: from README
|
126
|
+
ih = InsensitiveHash[ h ]
|
127
|
+
ih.underscore = true
|
128
|
+
assert ih[:a_key_with_spaces]
|
129
|
+
assert ih.underscore?
|
76
130
|
end
|
77
131
|
|
78
132
|
def test_delete
|
@@ -88,13 +142,36 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
88
142
|
|
89
143
|
def test_merge
|
90
144
|
[:merge, :update].each do |method|
|
91
|
-
ih = InsensitiveHash[:a => 1]
|
145
|
+
ih = InsensitiveHash[:a => 1, 'hello world' => 2]
|
92
146
|
ih2 = ih.send(method, :b => 2)
|
93
147
|
|
94
|
-
assert_equal [:a], ih.keys
|
95
|
-
assert_equal [:a, :b], ih2.keys
|
148
|
+
assert_equal [:a, 'hello world'], ih.keys
|
149
|
+
assert_equal [:a, 'hello world', :b], ih2.keys
|
96
150
|
assert ih2.has_key?('B'), 'correctly merged another hash'
|
97
151
|
|
152
|
+
assert_nil ih[:hello_world]
|
153
|
+
assert_nil ih2[:hello_world]
|
154
|
+
|
155
|
+
ih.underscore = true
|
156
|
+
assert_equal 2, ih[:hello_world]
|
157
|
+
assert_equal 2, ih.send(method, :b => 2)[:hello_world]
|
158
|
+
|
159
|
+
ih.underscore = false
|
160
|
+
assert_nil ih[:hello_world]
|
161
|
+
assert_nil ih.send(method, :b => 2)[:hello_world]
|
162
|
+
|
163
|
+
ih.default = 10
|
164
|
+
assert_equal 10, ih.send(method, :b => 2)[:anything]
|
165
|
+
|
166
|
+
ih.default = nil
|
167
|
+
assert_nil ih.send(method, :b => 2)[:anything]
|
168
|
+
|
169
|
+
ih.default_proc = proc { |h, k| h[k] = :default }
|
170
|
+
mh = ih.send(method, :b => 2)
|
171
|
+
assert !mh.has_key?(:anything)
|
172
|
+
assert_equal :default, mh[:anything]
|
173
|
+
assert mh.has_key?(:anything)
|
174
|
+
|
98
175
|
ih2.delete 'b'
|
99
176
|
assert ih2.has_key?('B') == false
|
100
177
|
end
|
@@ -114,6 +191,32 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
114
191
|
end
|
115
192
|
end
|
116
193
|
|
194
|
+
def test_merge_clash
|
195
|
+
ih = InsensitiveHash.new
|
196
|
+
ih2 = InsensitiveHash.new
|
197
|
+
ih2.underscore = true
|
198
|
+
|
199
|
+
[:merge, :merge!, :update, :update!].each do |method|
|
200
|
+
[ih, ih2].each do |h|
|
201
|
+
assert_raise(InsensitiveHash::KeyClashError) {
|
202
|
+
h.send(method, { :a => 1, :A => 1, 'A' => 1})
|
203
|
+
}
|
204
|
+
assert_raise(InsensitiveHash::KeyClashError) {
|
205
|
+
h.send(method, { 'a' => 1, 'A' => 1 })
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
ih.send(method, { :hello_world => 1, 'hello world' => 2})
|
210
|
+
assert_raise(InsensitiveHash::KeyClashError) {
|
211
|
+
ih2.send(method, { :hello_world => 1, 'hello world' => 2})
|
212
|
+
}
|
213
|
+
end
|
214
|
+
|
215
|
+
assert_raise(InsensitiveHash::KeyClashError) {
|
216
|
+
ih.merge({ :a => 1, :A => 1, 'A' => 1})
|
217
|
+
}
|
218
|
+
end
|
219
|
+
|
117
220
|
def test_assoc
|
118
221
|
h = InsensitiveHash[{
|
119
222
|
"colors" => ["red", "blue", "green"],
|
@@ -248,6 +351,41 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
248
351
|
|
249
352
|
assert !h.has_key?('A')
|
250
353
|
assert h.has_key?('B')
|
354
|
+
|
355
|
+
# Default value
|
356
|
+
h.replace(Hash.new(5))
|
357
|
+
assert_equal 5, h[:anything]
|
358
|
+
assert_equal [], h.keys
|
359
|
+
|
360
|
+
# Default proc
|
361
|
+
h.replace(Hash.new { |h, k| h[k] = :default })
|
362
|
+
assert_equal :default, h[:anything]
|
363
|
+
assert_equal [:anything], h.keys
|
364
|
+
|
365
|
+
# underscore property of self
|
366
|
+
assert !h.underscore?
|
367
|
+
h.replace(InsensitiveHash['hello world' => 1].tap { |ih| ih.underscore = true })
|
368
|
+
assert h.underscore?
|
369
|
+
assert_equal 1, h[:hello_world]
|
370
|
+
|
371
|
+
h = InsensitiveHash.new
|
372
|
+
assert_raise(InsensitiveHash::KeyClashError) {
|
373
|
+
h.replace({ 'a' => 1, :A => 2 })
|
374
|
+
}
|
375
|
+
|
376
|
+
# TODO: FIXME
|
377
|
+
# underscore property of other
|
378
|
+
h = InsensitiveHash.new
|
379
|
+
oh = InsensitiveHash[ 'hello world' => 1 ]
|
380
|
+
oh.underscore = true
|
381
|
+
assert !h.underscore?
|
382
|
+
h.replace(oh)
|
383
|
+
assert h.underscore?
|
384
|
+
|
385
|
+
oh.underscore = false
|
386
|
+
oh[:hello_world => 2]
|
387
|
+
h.replace(oh)
|
388
|
+
assert !h.underscore?
|
251
389
|
end
|
252
390
|
|
253
391
|
def test_rassoc
|
@@ -278,5 +416,120 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
278
416
|
assert_equal 3, h.fetch(:c) { 3 }
|
279
417
|
assert_raise(KeyError) { h.fetch('D') }
|
280
418
|
end
|
419
|
+
|
420
|
+
def test_underscore
|
421
|
+
h = InsensitiveHash[{'Key with spaces' => 1}]
|
422
|
+
|
423
|
+
assert_equal 1, h['key with spaces']
|
424
|
+
assert_nil h[:key_with_spaces]
|
425
|
+
|
426
|
+
test_keys = [
|
427
|
+
:KEY_WITH_SPACES,
|
428
|
+
:Key_with_spaces,
|
429
|
+
:key_with_spaces,
|
430
|
+
'key with_spaces',
|
431
|
+
'KEY_WITH spaces'
|
432
|
+
]
|
433
|
+
|
434
|
+
10.times do
|
435
|
+
assert_raise(ArgumentError) { h.underscore = 'wat' }
|
436
|
+
assert !h.underscore?
|
437
|
+
h.underscore = true
|
438
|
+
assert h.underscore?
|
439
|
+
|
440
|
+
|
441
|
+
test_keys.each do |k|
|
442
|
+
assert_equal 1, h[k]
|
443
|
+
end
|
444
|
+
assert_equal ['Key with spaces'], h.keys
|
445
|
+
|
446
|
+
h.underscore = false
|
447
|
+
assert !h.underscore?
|
448
|
+
assert_equal 1, h['KEY WITH SPACES']
|
449
|
+
test_keys.each do |k|
|
450
|
+
assert_nil h[k]
|
451
|
+
end
|
452
|
+
assert_equal ['Key with spaces'], h.keys
|
453
|
+
end
|
454
|
+
|
455
|
+
h.underscore = true
|
456
|
+
test_keys.each do |tk|
|
457
|
+
h[tk] = 1
|
458
|
+
end
|
459
|
+
|
460
|
+
assert_equal [test_keys.last], h.keys
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_underscore_inheritance
|
464
|
+
h = InsensitiveHash[
|
465
|
+
{
|
466
|
+
'Key with spaces' => {
|
467
|
+
'Another key with spaces' => 1
|
468
|
+
},
|
469
|
+
'Key 2 with spaces' =>
|
470
|
+
InsensitiveHash['Yet another key with spaces' => 2].tap { |ih| ih.underscore = true },
|
471
|
+
'Key 3 with spaces' =>
|
472
|
+
InsensitiveHash['Yet another key with spaces' => 3]
|
473
|
+
}
|
474
|
+
]
|
475
|
+
|
476
|
+
assert_equal 1, h['key with spaces']['another key with spaces']
|
477
|
+
assert_equal false, h['key with spaces'].underscore?
|
478
|
+
assert_nil h['key with spaces'][:another_key_with_spaces]
|
479
|
+
assert_nil h[:key_with_spaces]
|
480
|
+
|
481
|
+
assert_equal 2, h['key 2 with spaces']['yet another key with spaces']
|
482
|
+
assert_equal 2, h['key 2 with spaces'][:yet_another_key_with_spaces]
|
483
|
+
assert_nil h[:key_2_with_spaces]
|
484
|
+
|
485
|
+
assert_equal 3, h['key 3 with spaces']['yet another key with spaces']
|
486
|
+
assert_nil h['key 3 with spaces'][:yet_another_key_with_spaces]
|
487
|
+
assert_nil h[:key_3_with_spaces]
|
488
|
+
|
489
|
+
h.underscore = true
|
490
|
+
assert_equal true, h[:key_with_spaces].underscore?
|
491
|
+
assert_equal 1, h[:key_with_spaces][:another_key_with_spaces]
|
492
|
+
assert_equal true, h[:key_2_with_spaces].underscore?
|
493
|
+
assert_equal 2, h[:key_2_with_spaces][:yet_another_key_with_spaces]
|
494
|
+
assert_equal true, h[:key_3_with_spaces].underscore?
|
495
|
+
assert_equal 3, h[:key_3_with_spaces][:yet_another_key_with_spaces]
|
496
|
+
|
497
|
+
h.underscore = false
|
498
|
+
assert_nil h[:key_with_spaces]
|
499
|
+
assert_nil h[:key_2_with_spaces]
|
500
|
+
assert_nil h[:key_3_with_spaces]
|
501
|
+
|
502
|
+
assert_equal false, h.underscore?
|
503
|
+
assert_equal true, h['key 2 with spaces'].underscore?
|
504
|
+
assert_equal true, h['key 3 with spaces'].underscore?
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_underscore_clash
|
508
|
+
h = InsensitiveHash.new
|
509
|
+
h['hello world'] = 1
|
510
|
+
h['HELLO_world'] = 2
|
511
|
+
assert_equal 1, h['HELLO WORLD']
|
512
|
+
assert_equal 2, h['HELLO_WORLD']
|
513
|
+
assert_equal ['hello world', 'HELLO_world'], h.keys
|
514
|
+
|
515
|
+
assert_raise(InsensitiveHash::KeyClashError) { h.underscore = true }
|
516
|
+
h.delete('hello world')
|
517
|
+
h.underscore = true
|
518
|
+
|
519
|
+
assert_equal ['HELLO_world'], h.keys
|
520
|
+
assert_equal 2, h['HELLO WORLD']
|
521
|
+
assert_equal 2, h[:HELLO_WORLD]
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_unset_underscore
|
525
|
+
h = InsensitiveHash.new
|
526
|
+
h.underscore = true
|
527
|
+
h[:hello_world] = 1
|
528
|
+
h.underscore = false
|
529
|
+
h['hello world'] = 2
|
530
|
+
|
531
|
+
assert_equal [:hello_world, 'hello world'], h.keys
|
532
|
+
assert_equal 2, h['Hello World']
|
533
|
+
end
|
281
534
|
end
|
282
535
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: insensitive_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152875840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 2.3.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2152875840
|
25
25
|
description: Hash with case-insensitive, Symbol/String-indifferent key access
|
26
26
|
email:
|
27
27
|
- junegunn.c@gmail.com
|