hashlib 0.0.32 → 0.0.33
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/lib/hashlib.rb +62 -8
- metadata +1 -1
data/lib/hashlib.rb
CHANGED
@@ -1,3 +1,48 @@
|
|
1
|
+
class DeferredHashManipulator
|
2
|
+
def initialize(hash)
|
3
|
+
@hash = hash
|
4
|
+
@ops = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def set(path, value)
|
8
|
+
@ops << {
|
9
|
+
:type => :set,
|
10
|
+
:path => path,
|
11
|
+
:value => value
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def unset(path)
|
16
|
+
@ops << {
|
17
|
+
:type => :unset,
|
18
|
+
:path => path
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def peek()
|
23
|
+
@hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def pending_operations()
|
27
|
+
@ops
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply()
|
31
|
+
@ops.each do |op|
|
32
|
+
case op[:type]
|
33
|
+
when :set
|
34
|
+
@hash.rset(op[:path], op[:value])
|
35
|
+
when :unset
|
36
|
+
@hash.unset(op[:path])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
@ops = []
|
41
|
+
|
42
|
+
@hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
1
46
|
class Hash
|
2
47
|
def diff(other)
|
3
48
|
self.keys.inject({}) do |memo, key|
|
@@ -155,45 +200,54 @@ class Hash
|
|
155
200
|
end
|
156
201
|
|
157
202
|
def each_recurse(options={}, &block)
|
158
|
-
|
203
|
+
rv = {}
|
204
|
+
dhm = (options[:dhm] || DeferredHashManipulator.new(rv))
|
205
|
+
|
206
|
+
self.inject(rv) do |h, (k, v)|
|
159
207
|
path = [*options[:path]]+[k]
|
208
|
+
|
160
209
|
h[k] = v
|
161
210
|
|
162
211
|
if v.is_a?(Hash)
|
163
212
|
if options[:intermediate] === true
|
164
|
-
yield(k.to_s, v, path,
|
213
|
+
yield(k.to_s, v, path, dhm)
|
165
214
|
end
|
166
215
|
|
167
216
|
v.each_recurse(options.merge({
|
168
|
-
:path => path
|
217
|
+
:path => path,
|
218
|
+
:dhm => dhm
|
169
219
|
}), &block)
|
170
220
|
|
171
221
|
elsif v.is_a?(Array) and v.first.is_a?(Hash)
|
172
222
|
v.each_index do |i|
|
173
223
|
if v[i].is_a?(Hash)
|
174
224
|
if options[:intermediate] === true
|
175
|
-
yield(k.to_s, v[i], path,
|
225
|
+
yield(k.to_s, v[i], path, dhm, i)
|
176
226
|
end
|
177
227
|
|
178
228
|
v[i].each_recurse(options.merge({
|
179
229
|
:path => path,
|
180
|
-
:index => i
|
230
|
+
:index => i,
|
231
|
+
:dhm => dhm
|
181
232
|
}), &block)
|
182
233
|
end
|
183
234
|
end
|
184
235
|
|
185
236
|
else
|
186
|
-
rv = yield(k.to_s, v, path,
|
237
|
+
rv = yield(k.to_s, v, path, dhm, options[:index])
|
187
238
|
end
|
188
239
|
|
189
240
|
h
|
190
241
|
end
|
242
|
+
|
243
|
+
# apply any pending operations accumulated from the inject() loop and return
|
244
|
+
return dhm.apply()
|
191
245
|
end
|
192
246
|
|
193
247
|
def compact()
|
194
|
-
return each_recurse do |k,v,p,
|
248
|
+
return each_recurse do |k,v,p,dhm|
|
195
249
|
if v.nil? or (v.respond_to?(:empty?) and v.empty?)
|
196
|
-
|
250
|
+
dhm.unset(p)
|
197
251
|
end
|
198
252
|
end
|
199
253
|
end
|