lite-ruby 1.0.14 → 1.0.15
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile.lock +1 -1
- data/lib/lite/ruby/array.rb +221 -219
- data/lib/lite/ruby/boolean.rb +18 -16
- data/lib/lite/ruby/date.rb +18 -16
- data/lib/lite/ruby/enumerable.rb +169 -167
- data/lib/lite/ruby/hash.rb +309 -307
- data/lib/lite/ruby/helpers/date_helper.rb +97 -95
- data/lib/lite/ruby/helpers/time_helper.rb +79 -77
- data/lib/lite/ruby/integer.rb +57 -55
- data/lib/lite/ruby/kernel.rb +21 -19
- data/lib/lite/ruby/numeric.rb +189 -187
- data/lib/lite/ruby/object.rb +138 -136
- data/lib/lite/ruby/open_struct.rb +30 -28
- data/lib/lite/ruby/range.rb +23 -21
- data/lib/lite/ruby/string.rb +495 -493
- data/lib/lite/ruby/struct.rb +15 -13
- data/lib/lite/ruby/time.rb +27 -25
- data/lib/lite/ruby/version.rb +1 -1
- metadata +1 -1
data/lib/lite/ruby/hash.rb
CHANGED
@@ -1,413 +1,415 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
if Lite::Ruby.configuration.monkey_patches.include?('hash')
|
4
|
+
class Hash
|
4
5
|
|
5
|
-
|
6
|
+
class << self
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def zip(keys, values)
|
9
|
+
keys.size.times.with_object({}) { |i, hash| hash[keys[i]] = values[i] }
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def aka(new_key, old_key)
|
15
|
+
self[new_key] = self[old_key] if key?(old_key)
|
16
|
+
self
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def assert_valid_keys!(*valid_keys)
|
20
|
+
each_key do |key|
|
21
|
+
next if valid_keys.include?(key)
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
raise ArgumentError,
|
24
|
+
"Invalid key: #{key.inspect}." \
|
25
|
+
"Allowed keys are: #{valid_keys.map(&:inspect).join(', ')}"
|
26
|
+
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
def assert_all_valid_keys!(*valid_keys)
|
30
|
+
return assert_valid_keys!(*valid_keys) unless empty?
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
raise ArgumentError, 'An empty hash is not allowed'
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def assert_valid_values!(*valid_values)
|
36
|
+
each_value do |value|
|
37
|
+
next if valid_values.include?(value)
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
raise ArgumentError,
|
40
|
+
"Invalid value: #{value.inspect}." \
|
41
|
+
"Allowed values are: #{valid_values.map(&:inspect).join(', ')}"
|
42
|
+
end
|
41
43
|
end
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
45
|
+
def assert_all_valid_values!(*valid_values)
|
46
|
+
return assert_valid_values!(*valid_values) unless empty?
|
46
47
|
|
47
|
-
|
48
|
-
|
48
|
+
raise ArgumentError, 'An empty hash is not allowed'
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
# rubocop:disable Style/GuardClause
|
52
|
+
def bury(*args)
|
53
|
+
if args.count < 2
|
54
|
+
raise ArgumentError, '2 or more arguments required'
|
55
|
+
elsif args.count == 2
|
56
|
+
self[args[0]] = args[1]
|
57
|
+
else
|
58
|
+
arg = args.shift
|
59
|
+
self[arg] = {} unless self[arg]
|
60
|
+
self[arg].bury(*args) unless args.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
self
|
60
64
|
end
|
65
|
+
# rubocop:enable Style/GuardClause
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
68
|
+
def collate(*others)
|
69
|
+
hash = {}
|
65
70
|
|
66
|
-
|
67
|
-
def collate(*others)
|
68
|
-
hash = {}
|
71
|
+
each_key { |key| hash[key] = [] }
|
69
72
|
|
70
|
-
|
73
|
+
others.each do |other|
|
74
|
+
other.each_key { |key| hash[key] = [] }
|
75
|
+
end
|
71
76
|
|
72
|
-
|
73
|
-
other.each_key { |key| hash[key] = [] }
|
74
|
-
end
|
77
|
+
each { |key, val| hash[key] << val }
|
75
78
|
|
76
|
-
|
79
|
+
others.each do |other|
|
80
|
+
other.each { |key, val| hash[key] << val }
|
81
|
+
end
|
77
82
|
|
78
|
-
|
79
|
-
|
83
|
+
hash.each_value(&:flatten!)
|
84
|
+
hash
|
80
85
|
end
|
86
|
+
# rubocop:enable Metrics/MethodLength
|
81
87
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# rubocop:enable Metrics/MethodLength
|
86
|
-
|
87
|
-
def collate!(other_hash)
|
88
|
-
replace(collate(other_hash))
|
89
|
-
end
|
88
|
+
def collate!(other_hash)
|
89
|
+
replace(collate(other_hash))
|
90
|
+
end
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
def collect_keys
|
93
|
+
collect { |key, _| yield(key) }
|
94
|
+
end
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
96
|
+
def collect_values
|
97
|
+
collect { |_, val| yield(val) }
|
98
|
+
end
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
def dearray_values(idx = 0)
|
101
|
+
each_with_object({}) do |(key, val), hash|
|
102
|
+
hash[key] = case val
|
103
|
+
when Array then val[idx] || val[-1]
|
104
|
+
else val
|
105
|
+
end
|
106
|
+
end
|
105
107
|
end
|
106
|
-
end
|
107
108
|
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
def dearray_values!(idx = 0)
|
110
|
+
replace(dearray_values(idx))
|
111
|
+
end
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
113
|
+
def dearray_singular_values
|
114
|
+
each_with_object({}) do |(key, val), hash|
|
115
|
+
hash[key] = case val
|
116
|
+
when Array then val.size < 2 ? val[0] : val
|
117
|
+
else val
|
118
|
+
end
|
119
|
+
end
|
118
120
|
end
|
119
|
-
end
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
def dearray_singular_values!
|
123
|
+
replace(dearray_singular_values)
|
124
|
+
end
|
124
125
|
|
125
|
-
|
126
|
-
|
127
|
-
|
126
|
+
def deep_merge(other_hash, &block)
|
127
|
+
dup.deep_merge!(other_hash, &block)
|
128
|
+
end
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
130
|
+
def deep_merge!(other_hash, &block)
|
131
|
+
merge!(other_hash) do |key, this_val, other_val|
|
132
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
133
|
+
this_val.deep_merge(other_val, &block)
|
134
|
+
elsif block_given?
|
135
|
+
yield(key, this_val, other_val)
|
136
|
+
else
|
137
|
+
other_val
|
138
|
+
end
|
137
139
|
end
|
138
140
|
end
|
139
|
-
end
|
140
141
|
|
141
|
-
|
142
|
-
|
143
|
-
|
142
|
+
def delete_unless
|
143
|
+
delete_if { |key, val| !yield(key, val) }
|
144
|
+
end
|
144
145
|
|
145
|
-
|
146
|
-
|
147
|
-
|
146
|
+
def delete_values(*values)
|
147
|
+
each_key.with_object([]) do |key, array|
|
148
|
+
next unless values.include?(self[key])
|
148
149
|
|
149
|
-
|
150
|
-
|
150
|
+
array << key
|
151
|
+
delete(key)
|
152
|
+
end
|
151
153
|
end
|
152
|
-
end
|
153
154
|
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
def demote(key)
|
156
|
+
dup.demote!(key)
|
157
|
+
end
|
157
158
|
|
158
|
-
|
159
|
-
|
159
|
+
def demote!(key)
|
160
|
+
return self unless key?(key)
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
162
|
+
self[key] = delete(key)
|
163
|
+
self
|
164
|
+
end
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
|
166
|
+
def denillify(identity = 0)
|
167
|
+
dup.denillify!(identity)
|
168
|
+
end
|
168
169
|
|
169
|
-
|
170
|
-
|
171
|
-
|
170
|
+
def denillify!(identity = 0)
|
171
|
+
each { |key, val| self[key] = val || identity }
|
172
|
+
end
|
172
173
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
174
|
+
def diff(hash)
|
175
|
+
h1 = dup.delete_if { |k, v| hash[k] == v }
|
176
|
+
h2 = hash.dup.delete_if { |k, _| key?(k) }
|
177
|
+
h1.merge(h2)
|
178
|
+
end
|
178
179
|
|
179
|
-
|
180
|
-
|
181
|
-
|
180
|
+
def except(*keys)
|
181
|
+
dup.except!(*keys)
|
182
|
+
end
|
182
183
|
|
183
|
-
|
184
|
-
|
185
|
-
|
184
|
+
def except!(*keys)
|
185
|
+
keys.each_with_object(self) { |key, _| delete(key) }
|
186
|
+
end
|
186
187
|
|
187
|
-
|
188
|
-
|
189
|
-
|
188
|
+
def extract!(*keys)
|
189
|
+
keys.each_with_object(self) { |key, hash| hash[key] = delete(key) if key?(key) }
|
190
|
+
end
|
190
191
|
|
191
|
-
|
192
|
-
|
193
|
-
|
192
|
+
def hmap(&block)
|
193
|
+
dup.hmap!(&block)
|
194
|
+
end
|
194
195
|
|
195
|
-
|
196
|
-
|
197
|
-
|
196
|
+
def hmap!
|
197
|
+
inject(self) { |hash, (key, val)| hash.merge(yield(key, val)) }
|
198
|
+
end
|
198
199
|
|
199
|
-
|
200
|
-
|
200
|
+
def insert(name, value)
|
201
|
+
return false if key?(name)
|
201
202
|
|
202
|
-
|
203
|
-
|
204
|
-
|
203
|
+
store(name, value)
|
204
|
+
true
|
205
|
+
end
|
205
206
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
207
|
+
def invert
|
208
|
+
each_pair.with_object({}) do |(key, val), hash|
|
209
|
+
if val.is_a?(Array)
|
210
|
+
val.each { |x| hash[x] = (hash.key?(x) ? [key, hash[x]].flatten : key) }
|
211
|
+
else
|
212
|
+
hash[val] = (hash.key?(val) ? [key, hash[val]].flatten : key)
|
213
|
+
end
|
212
214
|
end
|
213
215
|
end
|
214
|
-
end
|
215
216
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
217
|
+
def keys?(*check_keys)
|
218
|
+
unknown_keys = check_keys - keys
|
219
|
+
unknown_keys.empty?
|
220
|
+
end
|
220
221
|
|
221
|
-
|
222
|
+
alias has_keys? keys?
|
222
223
|
|
223
|
-
|
224
|
-
|
225
|
-
|
224
|
+
def nillify
|
225
|
+
dup.nillify!
|
226
|
+
end
|
226
227
|
|
227
|
-
|
228
|
-
|
229
|
-
|
228
|
+
def nillify!
|
229
|
+
each do |key, val|
|
230
|
+
self[key] = nil if !val.nil? && (val.try(:blank?) || val.try(:to_s).blank?)
|
231
|
+
end
|
230
232
|
end
|
231
|
-
end
|
232
233
|
|
233
|
-
|
234
|
-
|
235
|
-
|
234
|
+
def only_fill(*keys, placeholder: nil)
|
235
|
+
keys.each_with_object({}) { |key, hash| hash[key] = key?(key) ? self[key] : placeholder }
|
236
|
+
end
|
236
237
|
|
237
|
-
|
238
|
-
|
239
|
-
|
238
|
+
def only_fill!(*keys, placeholder: nil)
|
239
|
+
replace(only_fill(*keys, placeholder: placeholder))
|
240
|
+
end
|
240
241
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
242
|
+
def only_keys?(*check_keys)
|
243
|
+
unknown_keys = keys - check_keys
|
244
|
+
unknown_keys.empty?
|
245
|
+
end
|
245
246
|
|
246
|
-
|
247
|
+
alias has_only_keys? only_keys?
|
247
248
|
|
248
|
-
|
249
|
-
|
250
|
-
|
249
|
+
def pair?(key, value)
|
250
|
+
self[key] == value
|
251
|
+
end
|
251
252
|
|
252
|
-
|
253
|
-
|
254
|
-
|
253
|
+
def promote(key)
|
254
|
+
dup.promote!(key)
|
255
|
+
end
|
255
256
|
|
256
|
-
|
257
|
-
|
257
|
+
def promote!(key)
|
258
|
+
return self unless key?(key)
|
258
259
|
|
259
|
-
|
260
|
-
|
260
|
+
{ key => delete(key) }.merge(self)
|
261
|
+
end
|
261
262
|
|
262
|
-
|
263
|
-
|
264
|
-
|
263
|
+
def rename_keys(*keys)
|
264
|
+
dup.rename_keys!(*keys)
|
265
|
+
end
|
265
266
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
267
|
+
def rename_keys!(*keys)
|
268
|
+
keys = Hash[*keys]
|
269
|
+
keys.each_with_object(self) { |(key, val), hash| hash[val] = delete(key) if hash[key] }
|
270
|
+
end
|
270
271
|
|
271
|
-
|
272
|
-
|
273
|
-
|
272
|
+
def reverse_merge(other_hash)
|
273
|
+
other_hash.merge(self)
|
274
|
+
end
|
274
275
|
|
275
|
-
|
276
|
-
|
277
|
-
|
276
|
+
def reverse_merge!(other_hash)
|
277
|
+
other_hash.merge!(self)
|
278
|
+
end
|
278
279
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
280
|
+
def sample
|
281
|
+
key = sample_key
|
282
|
+
[key, fetch(key)]
|
283
|
+
end
|
283
284
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
285
|
+
def sample!
|
286
|
+
key, value = sample
|
287
|
+
delete(key)
|
288
|
+
[key, value]
|
289
|
+
end
|
289
290
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
291
|
+
def sample_key
|
292
|
+
hash_keys = keys
|
293
|
+
hash_keys.at(Random.rand(hash_keys.size - 1))
|
294
|
+
end
|
294
295
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
296
|
+
def sample_key!
|
297
|
+
key, = sample
|
298
|
+
delete(key)
|
299
|
+
key
|
300
|
+
end
|
300
301
|
|
301
|
-
|
302
|
-
|
303
|
-
|
302
|
+
def sample_value
|
303
|
+
fetch(sample_key)
|
304
|
+
end
|
304
305
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
306
|
+
def sample_value!
|
307
|
+
key, value = sample
|
308
|
+
delete(key)
|
309
|
+
value
|
310
|
+
end
|
310
311
|
|
311
|
-
|
312
|
-
|
313
|
-
|
312
|
+
def shuffle
|
313
|
+
Hash[to_a.sample(size)]
|
314
|
+
end
|
314
315
|
|
315
|
-
|
316
|
-
|
317
|
-
|
316
|
+
def shuffle!
|
317
|
+
replace(shuffle)
|
318
|
+
end
|
318
319
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
320
|
+
def slice!(*keys)
|
321
|
+
omit = slice(*self.keys - keys)
|
322
|
+
hash = slice(*keys)
|
323
|
+
hash.default = default
|
324
|
+
hash.default_proc = default_proc if default_proc
|
325
|
+
replace(hash)
|
326
|
+
omit
|
327
|
+
end
|
327
328
|
|
328
|
-
|
329
|
-
|
329
|
+
alias only slice
|
330
|
+
alias only! slice!
|
330
331
|
|
331
|
-
|
332
|
-
|
333
|
-
|
332
|
+
def stringify_keys
|
333
|
+
each_with_object({}) { |(key, val), hash| hash[key.to_s] = val }
|
334
|
+
end
|
334
335
|
|
335
|
-
|
336
|
-
|
337
|
-
|
336
|
+
def stringify_keys!
|
337
|
+
replace(stringify_keys)
|
338
|
+
end
|
338
339
|
|
339
|
-
|
340
|
-
|
341
|
-
|
340
|
+
def strip
|
341
|
+
select { |_, val| !val.blank? }
|
342
|
+
end
|
342
343
|
|
343
|
-
|
344
|
-
|
345
|
-
|
344
|
+
def strip!
|
345
|
+
reject! { |_, val| val.blank? }
|
346
|
+
end
|
346
347
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
348
|
+
def symbolize_keys
|
349
|
+
each_with_object({}) do |(key, val), hash|
|
350
|
+
new_key = begin
|
351
|
+
key.to_s.to_sym
|
352
|
+
rescue StandardError
|
353
|
+
key
|
354
|
+
end
|
354
355
|
|
355
|
-
|
356
|
+
hash[new_key] = val
|
357
|
+
end
|
356
358
|
end
|
357
|
-
end
|
358
359
|
|
359
|
-
|
360
|
-
|
361
|
-
|
360
|
+
def symbolize_keys!
|
361
|
+
replace(symbolize_keys)
|
362
|
+
end
|
363
|
+
|
364
|
+
# rubocop:disable Metrics/MethodLength
|
365
|
+
def symbolize_and_underscore_keys
|
366
|
+
each_with_object({}) do |(key, val), hash|
|
367
|
+
new_key = begin
|
368
|
+
key.to_s
|
369
|
+
.gsub(/::/, '/')
|
370
|
+
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
371
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
372
|
+
.tr(' -', '_')
|
373
|
+
.downcase
|
374
|
+
.to_sym
|
375
|
+
rescue StandardError
|
376
|
+
key
|
377
|
+
end
|
362
378
|
|
363
|
-
|
364
|
-
|
365
|
-
each_with_object({}) do |(key, val), hash|
|
366
|
-
new_key = begin
|
367
|
-
key.to_s
|
368
|
-
.gsub(/::/, '/')
|
369
|
-
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
370
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
371
|
-
.tr(' -', '_')
|
372
|
-
.downcase
|
373
|
-
.to_sym
|
374
|
-
rescue StandardError
|
375
|
-
key
|
376
|
-
end
|
377
|
-
|
378
|
-
hash[new_key] = val
|
379
|
+
hash[new_key] = val
|
380
|
+
end
|
379
381
|
end
|
380
|
-
|
381
|
-
# rubocop:enable Metrics/MethodLength
|
382
|
+
# rubocop:enable Metrics/MethodLength
|
382
383
|
|
383
|
-
|
384
|
-
|
385
|
-
|
384
|
+
def symbolize_and_underscore_keys!
|
385
|
+
replace(symbolize_and_underscore_keys)
|
386
|
+
end
|
386
387
|
|
387
|
-
|
388
|
-
|
389
|
-
|
388
|
+
def to_object
|
389
|
+
JSON.parse(to_json, object_class: OpenStruct)
|
390
|
+
end
|
390
391
|
|
391
|
-
|
392
|
+
alias to_o to_object
|
392
393
|
|
393
|
-
|
394
|
-
|
395
|
-
|
394
|
+
def update_each
|
395
|
+
replace(each_with_object({}) { |(key, val), hash| hash.update(yield(key, val)) })
|
396
|
+
end
|
396
397
|
|
397
|
-
|
398
|
-
|
398
|
+
def update_keys
|
399
|
+
return to_enum(:update_keys) unless block_given?
|
399
400
|
|
400
|
-
|
401
|
-
|
401
|
+
replace(each_with_object({}) { |(key, val), hash| hash[yield(key)] = val })
|
402
|
+
end
|
402
403
|
|
403
|
-
|
404
|
-
|
404
|
+
def update_values
|
405
|
+
return to_enum(:update_values) unless block_given?
|
405
406
|
|
406
|
-
|
407
|
-
|
407
|
+
replace(each_with_object({}) { |(key, val), hash| hash[key] = yield(val) })
|
408
|
+
end
|
408
409
|
|
409
|
-
|
410
|
-
|
411
|
-
|
410
|
+
def vacant?(key)
|
411
|
+
self[key].blank?
|
412
|
+
end
|
412
413
|
|
414
|
+
end
|
413
415
|
end
|