refinements 7.8.0 → 7.9.0

Sign up to get free protection for your applications and to get access to all the features.
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