insensitive_hash 0.1.0 → 0.2.0
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 +5 -0
- data/README.markdown +8 -3
- data/insensitive_hash.gemspec +1 -1
- data/lib/insensitive_hash.rb +1 -1
- data/lib/insensitive_hash/insensitive_hash.rb +82 -12
- data/lib/insensitive_hash/version.rb +1 -1
- data/test/test_insensitive_hash.rb +224 -27
- metadata +49 -45
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
### 0.2.0 / 2012/02/01
|
2
|
+
* Major rewrite
|
3
|
+
* Constructor syntaxes have been changed to match those of standard Hash (not backward-compatible)
|
4
|
+
* (Almost) Complete implementation of standard Hash spec.
|
5
|
+
|
1
6
|
### 0.1.0 / 2011/12/20
|
2
7
|
* Can opt-out of monkey-patching Hash with `require 'insensitive_hash/minimal'`
|
3
8
|
|
data/README.markdown
CHANGED
@@ -13,17 +13,22 @@ gem install insensitive_hash
|
|
13
13
|
require 'insensitive_hash'
|
14
14
|
|
15
15
|
# Monkey-patched Hash#insensitive method
|
16
|
-
{'abc' => 1, :def => 2}.insensitive
|
16
|
+
ih = {'abc' => 1, :def => 2}.insensitive
|
17
17
|
|
18
18
|
# Or,
|
19
|
-
InsensitiveHash
|
19
|
+
ih = InsensitiveHash[ :abc => 1, 'DEF' => 2 ]
|
20
|
+
ih = InsensitiveHash[ :abc, 1, 'DEF', 2 ]
|
21
|
+
|
22
|
+
# Revert to normal Hash
|
23
|
+
h = ih.sensitive
|
24
|
+
h = ih.to_hash
|
20
25
|
```
|
21
26
|
|
22
27
|
If you don't like to have Hash#insensitive method, `require 'insensitive_hash/minimal'`
|
23
28
|
|
24
29
|
### Basic usage
|
25
30
|
```ruby
|
26
|
-
ih = InsensitiveHash
|
31
|
+
ih = InsensitiveHash[:abc => 1, 'DEF' => 2]
|
27
32
|
|
28
33
|
# Case-insensitive, Symbol/String-indifferent access.
|
29
34
|
ih['Abc'] # 1
|
data/insensitive_hash.gemspec
CHANGED
data/lib/insensitive_hash.rb
CHANGED
@@ -1,36 +1,97 @@
|
|
1
1
|
class InsensitiveHash < Hash
|
2
|
-
|
2
|
+
attr_reader :key_map
|
3
|
+
|
4
|
+
def initialize default = nil, &block
|
5
|
+
if block_given?
|
6
|
+
super &block
|
7
|
+
else
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
3
11
|
@key_map = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a normal, sensitive Hash
|
15
|
+
# @return [Hash]
|
16
|
+
def to_hash
|
17
|
+
{}.merge self
|
18
|
+
end
|
19
|
+
alias sensitive to_hash
|
4
20
|
|
5
|
-
|
6
|
-
|
21
|
+
def self.[] *init
|
22
|
+
h = Hash[*init]
|
23
|
+
InsensitiveHash.new.tap do |ih|
|
24
|
+
h.each do |key, value|
|
25
|
+
ih[key] = value
|
26
|
+
end
|
7
27
|
end
|
8
28
|
end
|
9
29
|
|
10
|
-
|
11
|
-
|
30
|
+
%w[[] assoc has_key? include? key? member?].each do |symb|
|
31
|
+
class_eval <<-EVAL
|
32
|
+
def #{symb} key
|
33
|
+
super lookup_key(key)
|
34
|
+
end
|
35
|
+
EVAL
|
12
36
|
end
|
13
37
|
|
14
38
|
def []= key, value
|
15
|
-
|
39
|
+
ekey = encode key
|
40
|
+
if @key_map.has_key? ekey
|
41
|
+
delete @key_map[ekey]
|
42
|
+
end
|
43
|
+
|
16
44
|
@key_map[encode key] = key
|
45
|
+
super(lookup_key(key), InsensitiveHash.wrap(value))
|
46
|
+
end
|
47
|
+
alias store []=
|
48
|
+
|
49
|
+
def merge! other_hash
|
50
|
+
other_hash.each do |key, value|
|
51
|
+
self[key] = value
|
52
|
+
end
|
53
|
+
self
|
54
|
+
end
|
55
|
+
alias update! merge!
|
17
56
|
|
18
|
-
|
57
|
+
def merge other_hash
|
58
|
+
InsensitiveHash[self].tap do |ih|
|
59
|
+
ih.merge! other_hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
alias update merge
|
63
|
+
|
64
|
+
def delete key, &block
|
65
|
+
super lookup_key(key, true), &block
|
66
|
+
end
|
67
|
+
|
68
|
+
def clear
|
69
|
+
@key_map.clear
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def replace other
|
74
|
+
clear
|
75
|
+
other.each do |k, v|
|
76
|
+
self[k] = v
|
77
|
+
end
|
19
78
|
end
|
20
79
|
|
21
|
-
def
|
22
|
-
super
|
80
|
+
def shift
|
81
|
+
super.tap do |ret|
|
82
|
+
@key_map.delete_if { |k, v| v == ret.first }
|
83
|
+
end
|
23
84
|
end
|
24
85
|
|
25
|
-
def
|
26
|
-
|
86
|
+
def values_at *keys
|
87
|
+
keys.map { |k| self[k] }
|
27
88
|
end
|
28
89
|
|
29
90
|
private
|
30
91
|
def self.wrap value
|
31
92
|
case value
|
32
93
|
when Hash
|
33
|
-
value.class == InsensitiveHash ? value : InsensitiveHash
|
94
|
+
value.class == InsensitiveHash ? value : InsensitiveHash[value]
|
34
95
|
when Array
|
35
96
|
value.map { |v| InsensitiveHash.wrap v }
|
36
97
|
else
|
@@ -38,6 +99,15 @@ private
|
|
38
99
|
end
|
39
100
|
end
|
40
101
|
|
102
|
+
def lookup_key key, delete = false
|
103
|
+
ekey = encode key
|
104
|
+
if @key_map.has_key?(ekey)
|
105
|
+
delete ? @key_map.delete(ekey) : @key_map[ekey]
|
106
|
+
else
|
107
|
+
key
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
41
111
|
def encode key
|
42
112
|
case key
|
43
113
|
when String
|
@@ -1,41 +1,21 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup(:default, :development)
|
2
4
|
require 'test/unit'
|
3
5
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
6
|
require 'insensitive_hash/minimal'
|
5
7
|
|
6
8
|
class TestInsensitiveHash < Test::Unit::TestCase
|
7
|
-
def test_from_hash
|
8
|
-
hash = {
|
9
|
-
'a' => 1,
|
10
|
-
'B' => 2,
|
11
|
-
:c => { :D => [ { 'e' => 3 } ] }
|
12
|
-
}
|
13
|
-
|
14
|
-
assert_raise(NoMethodError) {
|
15
|
-
hash.insensitive
|
16
|
-
}
|
17
|
-
|
18
|
-
require 'insensitive_hash'
|
19
|
-
[hash.insensitive, InsensitiveHash.new(hash)].each do |ih|
|
20
|
-
assert ih.is_a?(Hash)
|
21
|
-
assert_equal InsensitiveHash, ih.class
|
22
|
-
['c', 'C', :c, :C].each do |c|
|
23
|
-
assert_equal InsensitiveHash, ih[c].class
|
24
|
-
|
25
|
-
['d', 'D', :d, :D].each do |d|
|
26
|
-
assert_equal InsensitiveHash, ih[c][d].first.class
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
9
|
def test_has_key_set
|
33
10
|
ih = InsensitiveHash.new
|
34
11
|
ih['a'] = 1
|
35
|
-
ih
|
12
|
+
ih.store 'A', 2
|
36
13
|
|
37
14
|
['a', 'A', :a, :A].each do |a|
|
38
15
|
assert ih.has_key?(a)
|
16
|
+
assert ih.key?(a)
|
17
|
+
assert ih.include?(a)
|
18
|
+
assert ih.member?(a)
|
39
19
|
assert_equal 2, ih[a]
|
40
20
|
end
|
41
21
|
|
@@ -43,6 +23,7 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
43
23
|
assert_equal [2], ih.values
|
44
24
|
|
45
25
|
ih[:A] = 4
|
26
|
+
assert_equal ih.keys, [:A]
|
46
27
|
assert_equal [:A], ih.keys
|
47
28
|
assert_equal [4], ih.values
|
48
29
|
|
@@ -50,6 +31,7 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
50
31
|
assert ih.keys.include?(:A)
|
51
32
|
assert ih.keys.include?(:b)
|
52
33
|
assert_equal 2, ih.keys.length
|
34
|
+
assert_equal({ :c => 5 }, ih['B'])
|
53
35
|
assert_equal 5, ih['B']['C']
|
54
36
|
|
55
37
|
ih['c'] = [ { 'x' => 1 }, { :y => 2 } ]
|
@@ -68,12 +50,227 @@ class TestInsensitiveHash < Test::Unit::TestCase
|
|
68
50
|
assert_equal 50, ih[5]
|
69
51
|
end
|
70
52
|
|
53
|
+
def test_from_hash
|
54
|
+
hash = {
|
55
|
+
'a' => 1,
|
56
|
+
'B' => 2,
|
57
|
+
:c => { :D => [ { 'e' => 3 } ] }
|
58
|
+
}
|
59
|
+
|
60
|
+
assert_raise(NoMethodError) {
|
61
|
+
hash.insensitive
|
62
|
+
}
|
63
|
+
|
64
|
+
require 'insensitive_hash'
|
65
|
+
[hash.insensitive, InsensitiveHash[hash]].each do |ih|
|
66
|
+
assert ih.is_a?(Hash)
|
67
|
+
assert_equal InsensitiveHash, ih.class
|
68
|
+
['c', 'C', :c, :C].each do |c|
|
69
|
+
assert_equal InsensitiveHash, ih[c].class
|
70
|
+
|
71
|
+
['d', 'D', :d, :D].each do |d|
|
72
|
+
assert_equal InsensitiveHash, ih[c][d].first.class
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
71
78
|
def test_delete
|
72
|
-
ih = InsensitiveHash
|
79
|
+
ih = InsensitiveHash[:a => 1]
|
73
80
|
assert_equal [:a], ih.keys
|
74
81
|
assert_equal [1], ih.values
|
75
82
|
|
83
|
+
assert_equal nil, ih.delete('B')
|
76
84
|
assert_equal 1, ih.delete('A')
|
85
|
+
assert_equal :notfound, ih.delete('A') { |a| :notfound }
|
77
86
|
assert_equal [], ih.keys
|
78
87
|
end
|
88
|
+
|
89
|
+
def test_merge
|
90
|
+
[:merge, :update].each do |method|
|
91
|
+
ih = InsensitiveHash[:a => 1]
|
92
|
+
ih2 = ih.send(method, :b => 2)
|
93
|
+
|
94
|
+
assert_equal [:a], ih.keys
|
95
|
+
assert_equal [:a, :b], ih2.keys
|
96
|
+
assert ih2.has_key?('B'), 'correctly merged another hash'
|
97
|
+
|
98
|
+
ih2.delete 'b'
|
99
|
+
assert ih2.has_key?('B') == false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_merge!
|
104
|
+
[:merge!, :update!].each do |method|
|
105
|
+
ih = InsensitiveHash[:a => 1]
|
106
|
+
ih2 = ih.send(method, :b => 2)
|
107
|
+
|
108
|
+
assert_equal [:a, :b], ih.keys
|
109
|
+
assert_equal [:a, :b], ih2.keys
|
110
|
+
assert ih2.has_key?('B'), 'correctly merged another hash'
|
111
|
+
|
112
|
+
ih2.delete 'b'
|
113
|
+
assert ih2.has_key?('B') == false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_assoc
|
118
|
+
h = InsensitiveHash[{
|
119
|
+
"colors" => ["red", "blue", "green"],
|
120
|
+
:Letters => ["a", "b", "c" ]
|
121
|
+
}]
|
122
|
+
assert_equal [:Letters, ["a", "b", "c"]], h.assoc("letters")
|
123
|
+
assert_equal ["colors", ["red", "blue", "green"]], h.assoc(:COLORS)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_clear_empty?
|
127
|
+
h = InsensitiveHash[:a, 1]
|
128
|
+
h.clear
|
129
|
+
assert_equal [], h.keys
|
130
|
+
assert h.empty?
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_to_hash
|
134
|
+
h = InsensitiveHash[:a, 1, :b, {:c => 2}]
|
135
|
+
assert_equal 1, h[:A]
|
136
|
+
assert_equal 2, h['B']['C']
|
137
|
+
|
138
|
+
h = h.to_hash
|
139
|
+
assert_equal Hash, h.class
|
140
|
+
assert_equal nil, h[:A]
|
141
|
+
assert_equal 1, h[:a]
|
142
|
+
assert_equal 2, h[:b][:c]
|
143
|
+
pend("TBD: Recursive conversion") do
|
144
|
+
assert_equal nil, h[:b]['C']
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_compare_by_identity
|
149
|
+
pend 'Not Implemented'
|
150
|
+
|
151
|
+
key = 'a'
|
152
|
+
key2 = 'a'.clone
|
153
|
+
h = InsensitiveHash.new
|
154
|
+
h[key] = 1
|
155
|
+
h[:b] = 2
|
156
|
+
|
157
|
+
assert !h.compare_by_identity?
|
158
|
+
|
159
|
+
assert_equal 1, h['A']
|
160
|
+
assert_equal 2, h[:b]
|
161
|
+
h.compare_by_identity
|
162
|
+
|
163
|
+
assert h.compare_by_identity?
|
164
|
+
|
165
|
+
assert_equal nil, h[key2]
|
166
|
+
assert_equal nil, h[key]
|
167
|
+
assert_equal 2, h[:B]
|
168
|
+
|
169
|
+
h[key] = 3
|
170
|
+
assert_not_equal 'a'.object_id, key.object_id
|
171
|
+
assert_equal nil, h[key2]
|
172
|
+
assert_equal 3, h[key]
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_initializer
|
176
|
+
# Hash
|
177
|
+
h = InsensitiveHash[ { :a => 1 } ]
|
178
|
+
assert_equal 1, h['A']
|
179
|
+
assert_equal [:a], h.keys
|
180
|
+
assert_equal [1], h.values
|
181
|
+
|
182
|
+
# Pairs
|
183
|
+
h = InsensitiveHash[ 'a', 2, 3, 4 ]
|
184
|
+
assert_equal 2, h[:a]
|
185
|
+
|
186
|
+
# Wrong number of arguments
|
187
|
+
assert_raise(ArgumentError) { h = InsensitiveHash[ 'a', 2, 3 ] }
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_default
|
191
|
+
h = InsensitiveHash.new
|
192
|
+
assert_nil h.default
|
193
|
+
|
194
|
+
h = InsensitiveHash.new 'a'
|
195
|
+
assert_equal 'a', h.default
|
196
|
+
assert_equal 'a', h[:not_there]
|
197
|
+
|
198
|
+
h = InsensitiveHash.new { |h, k| h[k] = k == :right ? :ok : nil }
|
199
|
+
assert_equal nil, h.default
|
200
|
+
assert_equal nil, h.default(:wrong)
|
201
|
+
assert_equal :ok, h.default(:right)
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_delete_if
|
205
|
+
# FIXME: Test passes, but key_map not updated
|
206
|
+
h = InsensitiveHash[ :a => 100, :tmp_a => 200, :c => 300 ]
|
207
|
+
h.delete_if.each { |k, v| k == :tmp_a }
|
208
|
+
assert_equal [:a, :c], h.keys
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_has_key_after_delete
|
212
|
+
set = [:a, :A, 'a', 'A', :b, :B, 'b', 'B']
|
213
|
+
h = InsensitiveHash[ :a => 1, :b => 2 ]
|
214
|
+
|
215
|
+
set.each { |s| assert h.has_key?(s) }
|
216
|
+
h.delete_if { |e| true }
|
217
|
+
set.each { |s| assert !h.has_key?(s) }
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_nil
|
221
|
+
h = InsensitiveHash.new(1)
|
222
|
+
h[nil] = 2
|
223
|
+
assert h.has_key?(nil)
|
224
|
+
assert !h.has_key?(:not_there)
|
225
|
+
assert_equal 1, h[:not_there]
|
226
|
+
assert_equal 2, h[nil]
|
227
|
+
|
228
|
+
h = InsensitiveHash[ nil => 1 ]
|
229
|
+
assert_equal :notfound, h.delete('a') { :notfound }
|
230
|
+
assert_equal 1, h.delete(nil) { :notfound }
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_each
|
234
|
+
h = InsensitiveHash[{ :a => 1, :b => 2, :c => 3}]
|
235
|
+
assert_equal 3, h.each.count
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_fetch
|
239
|
+
h = InsensitiveHash[{ :a => 1, :b => 2, :c => 3}]
|
240
|
+
assert_raise(KeyError) { h.fetch('D') }
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_has_value
|
244
|
+
h = InsensitiveHash[{ :a => 1, :b => 2, :c => 3}]
|
245
|
+
assert h.value?(3)
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_replace
|
249
|
+
h = InsensitiveHash[:a, 1]
|
250
|
+
assert h.has_key?('A')
|
251
|
+
|
252
|
+
h.replace({ :b => 2 })
|
253
|
+
|
254
|
+
assert !h.has_key?('A')
|
255
|
+
assert h.has_key?('B')
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_rassoc
|
259
|
+
a = InsensitiveHash[{1=> "one", 2 => "two", 3 => "three", "ii" => "two"}]
|
260
|
+
assert_equal [2, "two"], a.rassoc("two")
|
261
|
+
assert_nil a.rassoc("four")
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_shift
|
265
|
+
h = InsensitiveHash[{:a => 1, :b => 2}]
|
266
|
+
assert_equal [:a, 1], h.shift
|
267
|
+
assert !h.has_key?('A')
|
268
|
+
assert h.has_key?('B')
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_values_at
|
272
|
+
h = InsensitiveHash[{:a => 1, :b => 2}]
|
273
|
+
assert_equal [2, 1], h.values_at('B', :A)
|
274
|
+
end
|
79
275
|
end
|
276
|
+
|
metadata
CHANGED
@@ -1,66 +1,70 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: insensitive_hash
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
|
7
|
+
authors:
|
8
|
+
- Junegunn Choi
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
date: 2012-02-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: test-unit
|
16
|
+
requirement: &2156362640 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.3.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2156362640
|
16
25
|
description: Hash with case-insensitive, Symbol/String-indifferent key access
|
17
|
-
email:
|
18
|
-
|
26
|
+
email:
|
27
|
+
- junegunn.c@gmail.com
|
19
28
|
executables: []
|
20
|
-
|
21
29
|
extensions: []
|
22
|
-
|
23
30
|
extra_rdoc_files: []
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
- test/test_insensitive_hash.rb
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- CHANGELOG.markdown
|
34
|
+
- Gemfile
|
35
|
+
- LICENSE.txt
|
36
|
+
- README.markdown
|
37
|
+
- Rakefile
|
38
|
+
- insensitive_hash.gemspec
|
39
|
+
- lib/insensitive_hash.rb
|
40
|
+
- lib/insensitive_hash/insensitive_hash.rb
|
41
|
+
- lib/insensitive_hash/minimal.rb
|
42
|
+
- lib/insensitive_hash/version.rb
|
43
|
+
- test/test_insensitive_hash.rb
|
38
44
|
homepage: https://github.com/junegunn/insensitive_hash
|
39
45
|
licenses: []
|
40
|
-
|
41
46
|
post_install_message:
|
42
47
|
rdoc_options: []
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
51
|
none: false
|
48
|
-
requirements:
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
57
|
none: false
|
54
|
-
requirements:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
58
62
|
requirements: []
|
59
|
-
|
60
63
|
rubyforge_project: insensitive_hash
|
61
|
-
rubygems_version: 1.8.
|
64
|
+
rubygems_version: 1.8.15
|
62
65
|
signing_key:
|
63
66
|
specification_version: 3
|
64
67
|
summary: Case-insensitive Ruby Hash
|
65
|
-
test_files:
|
66
|
-
|
68
|
+
test_files:
|
69
|
+
- test/test_insensitive_hash.rb
|
70
|
+
has_rdoc:
|