refinements 7.8.0 → 7.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd72c4e1fda257b53dcd80a052db0ce99cd5b2987e531bea93f577e6b3b131f9
4
- data.tar.gz: 67b83319903a39425640eb0534eab280e7cb138e588476c635c5192afb08758d
3
+ metadata.gz: ba7c2934d38986ae19d3a41bdc1305164ebe2355bb30afa925eebbeb9746f962
4
+ data.tar.gz: 1945d2226c6ca304aa9958635aab6a87880b66e43566691c3ab509f5b2e77f6b
5
5
  SHA512:
6
- metadata.gz: 8fab91775e301f8765dd3156ab91e6abdf9395bdf767fbf859f80a5d3ea2bbebabef8dbe9e5e5a65e33443082a13e127ce3d85c1384b3939d753347384dea99e
7
- data.tar.gz: 74934f4fbb6336ad4c434961c865b826675a71b76f846faae7635e6e09d3aa99bd74a9c74d6f0289f2d63a0c3352c9e21aecb60e35c2485664879520b20a755d
6
+ metadata.gz: 34e601f3bfe0ebe6b35ddf54dea67ef9c33d7436fae5103a2ce03106a34026f1920a6f06369ba2516ceb0a550bb6868fcd5491084cca5b6dd20ed746b4772a39
7
+ data.tar.gz: 8e4d5de5f29f28df044333dbaa34fb0a6d9b34911e3e911bd5593caf4dfeb52c0c0767f5a01d164542c54a4d936453b14f6131c055234a5911d73c80673c7d14
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -15,66 +15,16 @@ toc::[]
15
15
 
16
16
  == Features
17
17
 
18
- * *Arrays*:
19
- ** `#compress` - Removes `nil` and empty values without modifying itself.
20
- ** `#compress!` - Removes `nil` and empty values while modifying itself.
21
- ** `#include` - Adds given array or elements without modifying itself.
22
- ** `#exclude` - Removes given array or elements without modifying itself.
23
- ** `#ring` - Answers a circular array which can enumerate before, current, after elements.
24
- * *BigDecimals*:
25
- ** `#inspect` - Allows one to inspect a big decimal with numeric representation.
26
- * *DateTimes*:
27
- ** `.utc` - Answers new DateTime object for current UTC date/time.
28
- * *Files*:
29
- ** `#rewrite` - When given a file path and a block, it provides the contents of the recently read
30
- file for manipulation and immediate writing back to the same file.
31
- * *Hashes*:
32
- ** `.infinite` - Answers new hash where missing keys, even deeply nested, answer an empty hash.
33
- ** `.with_default` - Answers new hash where every top-level missing key has the same default value.
34
- ** `#except` - Answers new hash with given keys removed without modifying itself.
35
- ** `#except!` - Answers new hash with given keys removed while modifying itself.
36
- ** `#symbolize_keys` - Converts keys to symbols without modifying itself.
37
- ** `#symbolize_keys!` - Converts keys to symbols while modifying itself.
38
- ** `#deep_merge` - Merges deeply nested hashes together without modifying itself.
39
- ** `#deep_merge!` - Merges deeply nested hashes together while modifying itself.
40
- ** `#deep_symbolize_keys` - Symbolizes keys of nested hash without modifying itself. Does not handle
41
- nested arrays, though.
42
- ** `#deep_symbolize_keys!` - Symbolizes keys of nested hash while modifying itself. Does not handle
43
- nested arrays, though.
44
- ** `#recurse` - Applies block to nested hash. Does not handle nested arrays, though.
45
- ** `#rekey` - Transforms keys per mapping (size of mapping can vary) without modifying itself.
46
- ** `#rekey!` - Transforms keys per mapping (size of mapping can vary) while modifying itself.
47
- ** `#reverse_merge` - Merges calling hash into passed in hash without modifying itself.
48
- ** `#reverse_merge!` - Merges calling hash into passed in hash while modifying itself.
49
- ** `#use` - Passes each hash value as a block argument for further processing.
50
- * *Pathnames*:
51
- ** `Pathname` - Conversion function (refined from `Kernel`) which can cast `nil` into a pathname.
52
- ** `#name` - Answers file name without extension.
53
- ** `#copy` - Copies file from current location to new location.
54
- ** `#directories` - Answers all or filtered directories for current path.
55
- ** `#extensions` - Answers file extensions as an array.
56
- ** `#files` - Answers all or filtered files for current path.
57
- ** `#gsub` - Same behavior as `String#gsub` but answers a path with patterns replaced with desired
58
- substitutes.
59
- ** `#relative_parent` - Answers relative path from parent directory. This is a complement to
60
- `#relative_path_from`.
61
- ** `#make_ancestors` - Ensures all ancestor directories are created for a path.
62
- ** `#rewrite` - When given a block, it provides the contents of the recently read file for
63
- manipulation and immediate writing back to the same file.
64
- ** `#touch` - Updates access and modification times for path. Defaults to current time.
65
- * *Strings*:
66
- ** `#first` - Answers first character of a string or first set of characters if given a number.
67
- ** `#last` - Answers last character of a string or last set of characters if given a number.
68
- ** `#blank?` - Answers `true`/`false` based on whether string is blank or not
69
- (i.e. `<space>`, `\n`, `\t`, `\r`).
70
- ** `#up` - Answers string with only first letter upcased.
71
- ** `#down` - Answers string with only first letter downcased.
72
- ** `#camelcase` - Answers a camelcased string.
73
- ** `#snakecase` - Answers a snakecased string.
74
- ** `#titleize` - Answers titleized string.
75
- ** `#to_bool` - Answers string as a boolean.
76
- * *String IOs*:
77
- ** `#reread` - Answers full string by rewinding to beginning of string and reading all content.
18
+ Enhances the following objects:
19
+
20
+ * Array
21
+ * BigDecimal
22
+ * DateTime
23
+ * File
24
+ * Hash
25
+ * Pathname
26
+ * String
27
+ * StringIO
78
28
 
79
29
  == Requirements
80
30
 
@@ -140,6 +90,7 @@ require "refinements/files"
140
90
  require "refinements/hashes"
141
91
  require "refinements/pathnames"
142
92
  require "refinements/strings"
93
+ require "refinements/string_ios"
143
94
  ----
144
95
 
145
96
  === Using
@@ -156,6 +107,7 @@ class Example
156
107
  using Refinements::Hashes
157
108
  using Refinements::Pathnames
158
109
  using Refinements::Strings
110
+ using Refinements::StringIOs
159
111
  end
160
112
  ----
161
113
 
@@ -165,25 +117,58 @@ The following sections demonstrate how each refinement enriches your objects wit
165
117
 
166
118
  ==== Array
167
119
 
120
+ ===== #compress
121
+
122
+ Removes `nil` and empty values without modifying itself.
123
+
168
124
  [source,ruby]
169
125
  ----
170
126
  example = ["An", nil, "", "Example"]
171
- example.compress # => ["An", "Example"]
172
- example # => ["An", nil, "", "Example"]
127
+ example.compress # => ["An", "Example"]
128
+ example # => ["An", nil, "", "Example"]
129
+ ----
130
+
131
+ ===== #compress!
132
+
133
+ Removes `nil` and empty values while modifying itself.
173
134
 
135
+ [source,ruby]
136
+ ----
174
137
  example = ["An", nil, "", "Example"]
175
- example.compress! # => ["An", "Example"]
176
- example # => ["An", "Example"]
138
+ example.compress! # => ["An", "Example"]
139
+ example # => ["An", "Example"]
140
+ ----
141
+
142
+ ===== #include
143
+
144
+ Adds given array or elements without modifying itself.
145
+
146
+ [source,ruby]
147
+ ----
148
+ [1, 2, 3].include [4, 5] # => [1, 2, 3, 4, 5]
149
+ [1, 2, 3].include 4, 5 # => [1, 2, 3, 4, 5]
150
+ ----
151
+
152
+ ===== #exclude
153
+
154
+ Removes given array or elements without modifying itself.
155
+
156
+ [source,ruby]
157
+ ----
158
+ [1, 2, 3, 4, 5].exclude [4, 5] # => [1, 2, 3]
159
+ [1, 2, 3, 4, 5].exclude 4, 5 # => [1, 2, 3]
160
+ ----
177
161
 
178
- [1, 2, 3].include [4, 5] # => [1, 2, 3, 4, 5]
179
- [1, 2, 3].include 4, 5 # => [1, 2, 3, 4, 5]
162
+ ===== #ring
180
163
 
181
- [1, 2, 3, 4, 5].exclude [4, 5] # => [1, 2, 3]
182
- [1, 2, 3, 4, 5].include 4, 5 # => [1, 2, 3, 4, 5]
164
+ Answers a circular array which can enumerate before, current, after elements.
183
165
 
166
+ [source,ruby]
167
+ ----
184
168
  example = [1, 2, 3]
185
169
  example.ring # => #<Enumerator: ...>
186
170
  example.ring { |(before, current, after)| puts "#{before} #{current} #{after}" }
171
+
187
172
  # [3 1 2]
188
173
  # [1 2 3]
189
174
  # [2 3 1]
@@ -191,6 +176,10 @@ example.ring { |(before, current, after)| puts "#{before} #{current} #{after}" }
191
176
 
192
177
  ==== Big Decimal
193
178
 
179
+ ===== #inspect
180
+
181
+ Allows one to inspect a big decimal with numeric representation.
182
+
194
183
  [source,ruby]
195
184
  ----
196
185
  BigDecimal.new("5.0E-10").inspect # => "#<BigDecimal:3fd3d458fe84 0.0000000005>"
@@ -198,6 +187,10 @@ BigDecimal.new("5.0E-10").inspect # => "#<BigDecimal:3fd3d458fe84 0.0000000005>"
198
187
 
199
188
  ==== DateTime
200
189
 
190
+ ===== .utc
191
+
192
+ Answers new DateTime object for current UTC date/time.
193
+
201
194
  [source,ruby]
202
195
  ----
203
196
  DateTime.utc # => #<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867000n),+0s,2299161j)>
@@ -205,6 +198,11 @@ DateTime.utc # => #<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867
205
198
 
206
199
  ==== File
207
200
 
201
+ ===== .rewrite
202
+
203
+ When given a file path and a block, it provides the contents of the recently read file for
204
+ manipulation and immediate writing back to the same file.
205
+
208
206
  [source,ruby]
209
207
  ----
210
208
  File.rewrite("/test.txt") { |content| content.gsub "[placeholder]", "example" }
@@ -212,154 +210,428 @@ File.rewrite("/test.txt") { |content| content.gsub "[placeholder]", "example" }
212
210
 
213
211
  ==== Hash
214
212
 
213
+ ===== .infinite
214
+
215
+ Answers new hash where missing keys, even deeply nested, answer an empty hash.
216
+
215
217
  [source,ruby]
216
218
  ----
217
219
  example = Hash.infinite
218
- example[:a] # => {}
219
- example[:a][:b][:c] # => {}
220
+ example[:a] # => {}
221
+ example[:a][:b][:c] # => {}
222
+ ----
220
223
 
224
+ ===== .with_default
225
+
226
+ Answers new hash where every top-level missing key has the same default value.
227
+
228
+ [source,ruby]
229
+ ----
221
230
  example = Hash.with_default ""
222
231
  example[:a] # => ""
232
+
223
233
  example = Hash.with_default []
224
234
  example[:b] # => []
235
+ ----
236
+
237
+ ===== #except
225
238
 
239
+ Answers new hash with given keys removed without modifying itself.
240
+
241
+ [source,ruby]
242
+ ----
226
243
  example = {a: 1, b: 2, c: 3}
227
- example.except :a, :b # => {c: 3}
228
- example # => {a: 1, b: 2, c: 3}
244
+ example.except :a, :b # => {c: 3}
245
+ example # => {a: 1, b: 2, c: 3}
246
+ ----
229
247
 
248
+ ===== #except!
249
+
250
+ Answers new hash with given keys removed while modifying itself.
251
+
252
+ [source,ruby]
253
+ ----
230
254
  example = {a: 1, b: 2, c: 3}
231
- example.except! :a, :b # => {c: 3}
232
- example # => {c: 3}
255
+ example.except! :a, :b # => {c: 3}
256
+ example # => {c: 3}
257
+ ----
258
+
259
+ ===== #flatten_keys
260
+
261
+ Flattens nested keys as top-level keys without modifying itself. Does not handle nested arrays,
262
+ though.
263
+
264
+ [source,ruby]
265
+ ----
266
+ {a: {b: 1}}.flatten_keys prefix: :test # => {test_a_b: 1}
267
+ {a: {b: 1}}.flatten_keys delimiter: :| # => {:"a|b" => 1}
233
268
 
269
+ {a: {b: 1}}.flatten_keys cast: :to_s # => {"a_b" => 1}
270
+ {"a" => {"b" => 1}}.flatten_keys cast: :to_sym # => {a_b: 1}
271
+
272
+ example = {a: {b: 1}}
273
+ example.flatten_keys # => {a_b: 1}
274
+ example # => {a: {b: 1}}
275
+ ----
276
+
277
+ ===== #flatten_keys!
278
+
279
+ Flattens nested keys as top-level keys while modifying itself. Does not handle nested arrays,
280
+ though.
281
+
282
+ [source,ruby]
283
+ ----
284
+ example = {a: {b: 1}}
285
+ example.flatten_keys! # => {a_b: 1}
286
+ example # => {a_b: 1}
287
+ ----
288
+
289
+ ===== #symbolize_keys
290
+
291
+ Converts keys to symbols without modifying itself.
292
+
293
+ [source,ruby]
294
+ ----
234
295
  example = {"a" => 1, "b" => 2}
235
- example.symbolize_keys # => {a: 1, b: 2}
236
- example # => {"a" => 1, "b" => 2}
296
+ example.symbolize_keys # => {a: 1, b: 2}
297
+ example # => {"a" => 1, "b" => 2}
298
+ ----
237
299
 
300
+ ===== #symbolize_keys!
301
+
302
+ Converts keys to symbols while modifying itself.
303
+
304
+ [source,ruby]
305
+ ----
238
306
  example = {"a" => 1, "b" => 2}
239
- example.symbolize_keys! # => {a: 1, b: 2}
240
- example # => {a: 1, b: 2}
307
+ example.symbolize_keys! # => {a: 1, b: 2}
308
+ example # => {a: 1, b: 2}
309
+ ----
241
310
 
242
- example = {a: 1, b: 2, c: 3}
243
- example.slice :a, :c # => {a: 1, c: 3}
244
- example # => {a: 1, b: 2, c: 3}
311
+ ===== #deep_merge
245
312
 
246
- example = {a: 1, b: 2, c: 3}
247
- example.slice! :a, :c # => {a: 1, c: 3}
248
- example # => {a: 1, c: 3}
313
+ Merges deeply nested hashes together without modifying itself.
249
314
 
315
+ [source,ruby]
316
+ ----
250
317
  example = {a: "A", b: {one: "One", two: "Two"}}
251
- example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
252
- example # => {a: "A", b: {one: "One", two: "Two"}}
318
+ example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
319
+ example # => {a: "A", b: {one: "One", two: "Two"}}
320
+ ----
321
+
322
+ ===== #deep_merge!
253
323
 
324
+ Merges deeply nested hashes together while modifying itself.
325
+
326
+ [source,ruby]
327
+ ----
254
328
  example = {a: "A", b: {one: "One", two: "Two"}}
255
- example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
256
- example # => {a: "A", b: {one: 1, two: "Two"}}
329
+ example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
330
+ example # => {a: "A", b: {one: 1, two: "Two"}}
331
+ ----
332
+
333
+ ===== #deep_symbolize_keys
257
334
 
335
+ Symbolizes keys of nested hash without modifying itself. Does not handle nested arrays, though.
336
+
337
+ [source,ruby]
338
+ ----
258
339
  example = {"a" => {"b" => 2}}
259
- example.deep_symbolize_keys # => {a: {b: 1}}
260
- example # => {"a" => {"b" => 2}}
340
+ example.deep_symbolize_keys # => {a: {b: 1}}
341
+ example # => {"a" => {"b" => 2}}
342
+ ----
343
+
344
+ ===== #deep_symbolize_keys!
261
345
 
346
+ Symbolizes keys of nested hash while modifying itself. Does not handle nested arrays, though.
347
+
348
+ [source,ruby]
349
+ ----
262
350
  example = {"a" => {"b" => 2}}
263
- example.deep_symbolize_keys! # => {a: {b: 1}}
264
- example # => {a: {b: 1}}
351
+ example.deep_symbolize_keys! # => {a: {b: 1}}
352
+ example # => {a: {b: 1}}
353
+ ----
265
354
 
355
+ ===== #recurse
356
+
357
+ Applies block to nested hash. Does not handle nested arrays, though.
358
+
359
+ [source,ruby]
360
+ ----
266
361
  example = {"a" => {"b" => 1}}
267
- example.recurse(&:symbolize_keys) # => {a: {b: 1}}
268
- example.recurse(&:invert) # => {{"b" => 1} => "a"}
362
+ example.recurse(&:symbolize_keys) # => {a: {b: 1}}
363
+ example.recurse(&:invert) # => {{"b" => 1} => "a"}
364
+ ----
365
+
366
+ ===== #rekey
367
+
368
+ Transforms keys per mapping (size of mapping can vary) without modifying itself.
269
369
 
370
+ [source,ruby]
371
+ ----
270
372
  example = {a: 1, b: 2, c: 3}
271
- example.rekey a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
272
- example # => {a: 1, b: 2, c: 3}
373
+ example.rekey a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
374
+ example # => {a: 1, b: 2, c: 3}
375
+ ----
273
376
 
377
+ ===== #rekey!
378
+
379
+ Transforms keys per mapping (size of mapping can vary) while modifying itself.
380
+
381
+ [source,ruby]
382
+ ----
274
383
  example = {a: 1, b: 2, c: 3}
275
- example.rekey! a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
276
- example # => {amber: 1, blue: 2, c: 3}
384
+ example.rekey! a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
385
+ example # => {amber: 1, blue: 2, c: 3}
386
+ ----
387
+
388
+ ===== #reverse_merge
277
389
 
390
+ Merges calling hash into passed in hash without modifying itself.
391
+
392
+ [source,ruby]
393
+ ----
278
394
  example = {a: 1, b: 2}
279
- example.reverse_merge a: 0, c: 3 # => {a: 1, b: 2, c: 3}
280
- example # => {a: 1, b: 2}
395
+ example.reverse_merge a: 0, c: 3 # => {a: 1, b: 2, c: 3}
396
+ example # => {a: 1, b: 2}
397
+ ----
281
398
 
399
+ ===== #reverse_merge!
400
+
401
+ Merges calling hash into passed in hash while modifying itself.
402
+
403
+ [source,ruby]
404
+ ----
282
405
  example = {a: 1, b: 2}
283
- example.reverse_merge! a: 0, c: 3 # => {a: 1, b: 2, c: 3}
284
- example # => {a: 1, b: 2, c: 3}
406
+ example.reverse_merge! a: 0, c: 3 # => {a: 1, b: 2, c: 3}
407
+ example # => {a: 1, b: 2, c: 3}
408
+ ----
409
+
410
+ ===== #use
411
+
412
+ Passes each hash value as a block argument for further processing.
285
413
 
414
+ [source,ruby]
415
+ ----
286
416
  example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
287
417
  example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
288
418
  ----
289
419
 
290
420
  ==== Pathname
291
421
 
422
+ ===== Pathname
423
+
424
+ Conversion function (refined from `Kernel`) which can cast `nil` into a pathname.
425
+
292
426
  [source,ruby]
293
427
  ----
294
428
  Pathname(nil) # => Pathname("")
429
+ ----
430
+
431
+ ===== #name
432
+
433
+ Answers file name without extension.
295
434
 
435
+ [source,ruby]
436
+ ----
296
437
  Pathname("example.txt").name # => Pathname("example")
438
+ ----
297
439
 
440
+ ===== #copy
441
+
442
+ Copies file from current location to new location.
443
+
444
+ [source,ruby]
445
+ ----
298
446
  Pathname("input.txt").copy Pathname("output.txt")
447
+ ----
448
+
449
+ ===== #directories
299
450
 
300
- Pathname("/example").directories # => [Pathname("a"), Pathname("b")]
301
- Pathname("/example").directories "a*" # => [Pathname("a")]
302
- Pathname("/example").directories flag: File::FNM_DOTMATCH # => [Pathname(".."), Pathname(".")]
451
+ Answers all or filtered directories for current path.
303
452
 
453
+ [source,ruby]
454
+ ----
455
+ Pathname("/example").directories # => [Pathname("a"), Pathname("b")]
456
+ Pathname("/example").directories "a*" # => [Pathname("a")]
457
+ Pathname("/example").directories flag: File::FNM_DOTMATCH # => [Pathname(".."), Pathname(".")]
458
+ ----
459
+
460
+ ===== #extensions
461
+
462
+ Answers file extensions as an array.
463
+
464
+ [source,ruby]
465
+ ----
304
466
  Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
467
+ ----
305
468
 
306
- Pathname("/example").files # => [Pathname("a.txt"), Pathname("a.png")]
307
- Pathname("/example").files "*.png" # => [Pathname("a.png")]
308
- Pathname("/example").files flag: File::FNM_DOTMATCH # => [Pathname(".ruby-version")]
469
+ ===== #files
309
470
 
310
- Pathname("/a/path/some/path").gsub("path", "test") # => Pathname("/a/test/some/test")
311
- Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test") # => Pathname("/test/some/test")
471
+ Answers all or filtered files for current path.
312
472
 
313
- Pathname("/one/two/three").relative_parent_from("/one") # => Pathname "two"
473
+ [source,ruby]
474
+ ----
475
+ Pathname("/example").files # => [Pathname("a.txt"), Pathname("a.png")]
476
+ Pathname("/example").files "*.png" # => [Pathname("a.png")]
477
+ Pathname("/example").files flag: File::FNM_DOTMATCH # => [Pathname(".ruby-version")]
478
+ ----
314
479
 
480
+ ===== #gsub
481
+
482
+ Same behavior as `String#gsub` but answers a path with patterns replaced with desired substitutes.
483
+
484
+ [source,ruby]
485
+ ----
486
+ Pathname("/a/path/some/path").gsub("path", "test")
487
+ # => Pathname("/a/test/some/test")
488
+
489
+ Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test")
490
+ # => Pathname("/test/some/test")
491
+ ----
492
+
493
+ ===== #relative_parent
494
+
495
+ Answers relative path from parent directory. This is a complement to `#relative_path_from`.
496
+
497
+ [source,ruby]
498
+ ----
499
+ Pathname("/one/two/three").relative_parent("/one") # => Pathname "two"
500
+ ----
501
+
502
+ ===== #make_ancestors
503
+
504
+ Ensures all ancestor directories are created for a path.
505
+
506
+ [source,ruby]
507
+ ----
315
508
  Pathname("/one/two").make_ancestors
316
- Pathname("/one").exist? # => true
317
- Pathname("/one/two").exist? # => false
509
+ Pathname("/one").exist? # => true
510
+ Pathname("/one/two").exist? # => false
511
+ ----
512
+
513
+ ===== #rewrite
514
+
515
+ When given a block, it provides the contents of the recently read file for manipulation and
516
+ immediate writing back to the same file.
318
517
 
518
+ [source,ruby]
519
+ ----
319
520
  Pathname("/test.txt").rewrite { |content| content.sub "[placeholder]", "example" }
521
+ ----
320
522
 
523
+ ===== #touch
524
+
525
+ Updates access and modification times for path. Defaults to current time.
526
+
527
+ [source,ruby]
528
+ ----
321
529
  Pathname("example.txt").touch
322
530
  Pathname("example.txt").touch at: Time.now - 1
323
531
  ----
324
532
 
325
533
  ==== String
326
534
 
535
+ ===== #first
536
+
537
+ Answers first character of a string or first set of characters if given a number.
538
+
539
+ [source,ruby]
540
+ ----
541
+ "example".first # => "e"
542
+ "example".first 4 # => "exam"
543
+ ----
544
+
545
+ ===== #last
546
+
547
+ Answers last character of a string or last set of characters if given a number.
548
+
327
549
  [source,ruby]
328
550
  ----
329
- "example".first # => "e"
330
- "example".first 4 # => "exam"
551
+ "instant".last # => "t"
552
+ "instant".last 3 # => "ant"
553
+ ----
554
+
555
+ ===== #blank?
331
556
 
332
- "instant".last # => "t"
333
- "instant".last 3 # => "ant"
557
+ Answers `true`/`false` based on whether string is blank, `<space>`, `\n`, `\t`, and/or `\r`.
334
558
 
559
+ [source,ruby]
560
+ ----
335
561
  " \n\t\r".blank? # => true
562
+ ----
563
+
564
+ ===== #up
336
565
 
566
+ Answers string with only first letter upcased.
567
+
568
+ [source,ruby]
569
+ ----
337
570
  "example".up # => "Example"
571
+ ----
572
+
573
+ ===== #down
338
574
 
575
+ Answers string with only first letter downcased.
576
+
577
+ [source,ruby]
578
+ ----
339
579
  "EXAMPLE".down # => "eXAMPLE"
580
+ ----
581
+
582
+ ===== #camelcase
340
583
 
584
+ Answers a camelcased string.
585
+
586
+ [source,ruby]
587
+ ----
341
588
  "this_is_an_example".camelcase # => "ThisIsAnExample"
589
+ ----
342
590
 
591
+ ===== #snakecase
592
+
593
+ Answers a snakecased string.
594
+
595
+ [source,ruby]
596
+ ----
343
597
  "ThisIsAnExample".snakecase # => "this_is_an_example"
598
+ ----
599
+
600
+ ===== #titleize
601
+
602
+ Answers titleized string.
344
603
 
604
+ [source,ruby]
605
+ ----
345
606
  "ThisIsAnExample".titleize # => "This Is An Example"
607
+ ----
346
608
 
347
- "true".to_bool # => true
348
- "yes".to_bool # => true
349
- "1".to_bool # => true
350
- "".to_bool # => false
351
- "example".to_bool # => false
609
+ ===== #to_bool
610
+
611
+ Answers string as a boolean.
612
+
613
+ [source,ruby]
614
+ ----
615
+ "true".to_bool # => true
616
+ "yes".to_bool # => true
617
+ "1".to_bool # => true
618
+ "".to_bool # => false
619
+ "example".to_bool # => false
352
620
  ----
353
621
 
354
622
  ==== String IO
355
623
 
624
+ ===== #reread
625
+
626
+ Answers full string by rewinding to beginning of string and reading all content.
627
+
356
628
  [source,ruby]
357
629
  ----
358
630
  io = StringIO.new
359
631
  io.write "This is a test."
360
- io.reread # => "This is a test."
361
632
 
362
- io.reread(4) => "This"
633
+ io.reread # => "This is a test."
634
+ io.reread 4 # => "This"
363
635
 
364
636
  buffer = "".dup
365
637
  io.reread(buffer: buffer)
@@ -21,6 +21,25 @@ module Refinements
21
21
  replace except(*keys)
22
22
  end
23
23
 
24
+ # :reek:TooManyStatements
25
+ def flatten_keys prefix: nil, delimiter: "_", cast: :to_sym
26
+ fail StandardError, "Unknown cast: #{cast}." unless %i[to_sym to_s].include? cast
27
+
28
+ reduce({}) do |flat, (key, value)|
29
+ flat_key = prefix ? "#{prefix}#{delimiter}#{key}" : key
30
+
31
+ next flat.merge flat_key.public_send(cast) => value unless value.is_a? self.class
32
+
33
+ flat.merge(
34
+ recurse { value.flatten_keys prefix: flat_key, delimiter: delimiter, cast: cast }
35
+ )
36
+ end
37
+ end
38
+
39
+ def flatten_keys! prefix: nil, delimiter: "_", cast: :to_sym
40
+ replace flatten_keys(prefix: prefix, delimiter: delimiter, cast: cast)
41
+ end
42
+
24
43
  def symbolize_keys
25
44
  reduce({}) { |hash, (key, value)| hash.merge key.to_sym => value }
26
45
  end
@@ -30,13 +49,9 @@ module Refinements
30
49
  end
31
50
 
32
51
  def deep_merge other
33
- dup.deep_merge! other
34
- end
35
-
36
- def deep_merge! other
37
52
  clazz = self.class
38
53
 
39
- merge! other do |_key, this_value, other_value|
54
+ merge other do |_key, this_value, other_value|
40
55
  if this_value.is_a?(clazz) && other_value.is_a?(clazz)
41
56
  this_value.deep_merge other_value
42
57
  else
@@ -45,12 +60,16 @@ module Refinements
45
60
  end
46
61
  end
47
62
 
63
+ def deep_merge! other
64
+ replace deep_merge(other)
65
+ end
66
+
48
67
  def deep_symbolize_keys
49
68
  recurse(&:symbolize_keys)
50
69
  end
51
70
 
52
71
  def deep_symbolize_keys!
53
- recurse(&:symbolize_keys!)
72
+ replace deep_symbolize_keys
54
73
  end
55
74
 
56
75
  def recurse &block
@@ -75,12 +94,12 @@ module Refinements
75
94
 
76
95
  def reverse_merge other
77
96
  warn "[DEPRECATION]: #reverse_merge is deprecated, use #merge instead."
78
- other.merge self
97
+ merge(other) { |_key, old_value, _new_value| old_value }
79
98
  end
80
99
 
81
100
  def reverse_merge! other
82
101
  warn "[DEPRECATION]: #reverse_merge! is deprecated, use #merge! instead."
83
- merge!(other) { |_key, old_value, _new_value| old_value }
102
+ replace reverse_merge(other)
84
103
  end
85
104
 
86
105
  def use &block
@@ -5,7 +5,7 @@ module Refinements
5
5
  module Identity
6
6
  NAME = "refinements"
7
7
  LABEL = "Refinements"
8
- VERSION = "7.8.0"
8
+ VERSION = "7.9.0"
9
9
  VERSION_LABEL = "#{LABEL} #{VERSION}"
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refinements
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.8.0
4
+ version: 7.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,7 +28,7 @@ cert_chain:
28
28
  2XV8FRa7/JimI07sPLC13eLY3xd/aYTi85Z782KIA4j0G8XEEWAX0ouBhlXPocZv
29
29
  QWc=
30
30
  -----END CERTIFICATE-----
31
- date: 2020-08-29 00:00:00.000000000 Z
31
+ date: 2020-09-19 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: bundler-audit
@@ -218,14 +218,14 @@ dependencies:
218
218
  requirements:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
- version: '0.18'
221
+ version: '0.19'
222
222
  type: :development
223
223
  prerelease: false
224
224
  version_requirements: !ruby/object:Gem::Requirement
225
225
  requirements:
226
226
  - - "~>"
227
227
  - !ruby/object:Gem::Version
228
- version: '0.18'
228
+ version: '0.19'
229
229
  description:
230
230
  email:
231
231
  - brooke@alchemists.io
metadata.gz.sig CHANGED
Binary file