refinements 7.10.0 → 7.15.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: 2b7b36399c299675bc98b26334acc2466c5c506849e34b36534f21d2eed72e57
4
- data.tar.gz: 0d00c8e399a0d43c21dafef5985e9d0eb51fe7d544fbe93f4d184eafa75018a8
3
+ metadata.gz: 756d9dcbbc60385370835ad8001dd4fb84f6848aba8ca51cbe949fcd2aaa72a4
4
+ data.tar.gz: f09562bfe5991533c166f5aa0aa215a3f2fe8df3604e85dd3404a7688df67980
5
5
  SHA512:
6
- metadata.gz: 558191fc552ba160302b9189b8bd2e3ed17ceaee226426cf9453c0c65b8ca0e771b9e85be1e5453c8c1438bc52511a45afc218c72329c17570a6036b65e9f91f
7
- data.tar.gz: 69436b5353f1541b644f9ca72346da713bd8bb1c0f9595983392881727f06ea46ecacdea1412a929981ee24e0243865c6ac9274e747f04d3584c85216e7e300b
6
+ metadata.gz: b37235bf15f3b959dd295a22c3e9c89dff28faa4124da955b0e27b2bef7db505d3093dc56369550d2863e6dc2ca3d10bbfe248da1e7a70f0eaee7fb351bd4e9f
7
+ data.tar.gz: 0c7aeed58557e626cc6494d761e79c4a0bcb60f42e79d83cef01676c9fd5fbf838dd97f4b89c3234a978455d3acfb6bdd3f715ed55dfed05a92e5f0e86d7426d
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -150,7 +150,7 @@ additional liability.
150
150
 
151
151
  END OF TERMS AND CONDITIONS
152
152
 
153
- Copyright link:https://www.alchemists.io[Alchemists].
153
+ Copyright 2015 link:https://www.alchemists.io/team/brooke_kuhlmann[Brooke Kuhlmann].
154
154
 
155
155
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
156
156
  compliance with the License. You may obtain a link:https://www.apache.org/licenses/LICENSE-2.0[copy]
@@ -6,6 +6,8 @@
6
6
 
7
7
  [link=http://badge.fury.io/rb/refinements]
8
8
  image::https://badge.fury.io/rb/refinements.svg[Gem Version]
9
+ [link=https://www.alchemists.io/projects/code_quality]
10
+ image::https://img.shields.io/badge/code_style-alchemists-brightgreen.svg[Alchemists Style Guide]
9
11
  [link=https://circleci.com/gh/bkuhlmann/refinements]
10
12
  image::https://circleci.com/gh/bkuhlmann/refinements.svg?style=svg[Circle CI Status]
11
13
 
@@ -22,9 +24,11 @@ Enhances the following objects:
22
24
  * DateTime
23
25
  * File
24
26
  * Hash
27
+ * IO
25
28
  * Pathname
26
29
  * String
27
30
  * StringIO
31
+ * Structs
28
32
 
29
33
  == Requirements
30
34
 
@@ -34,8 +38,6 @@ Enhances the following objects:
34
38
 
35
39
  == Setup
36
40
 
37
- === Production
38
-
39
41
  To install, run:
40
42
 
41
43
  [source,bash]
@@ -50,24 +52,6 @@ Add the following to your Gemfile file:
50
52
  gem "refinements"
51
53
  ----
52
54
 
53
- === Development
54
-
55
- To contribute, run:
56
-
57
- [source,bash]
58
- ----
59
- git clone https://github.com/bkuhlmann/refinements.git
60
- cd refinements
61
- bin/setup
62
- ----
63
-
64
- You can also use the IRB console for direct access to all objects:
65
-
66
- [source,bash]
67
- ----
68
- bin/console
69
- ----
70
-
71
55
  == Usage
72
56
 
73
57
  === Requires
@@ -79,7 +63,7 @@ If all refinements are not desired, add the following to your `+Gemfile+` instea
79
63
  gem "refinements", require: false
80
64
  ----
81
65
 
82
- then require the specific refinement, as needed. Example:
66
+ ...then require the specific refinement, as needed. Example:
83
67
 
84
68
  [source,ruby]
85
69
  ----
@@ -88,9 +72,11 @@ require "refinements/big_decimals"
88
72
  require "refinements/date_times"
89
73
  require "refinements/files"
90
74
  require "refinements/hashes"
75
+ require "refinements/ios"
91
76
  require "refinements/pathnames"
92
77
  require "refinements/strings"
93
78
  require "refinements/string_ios"
79
+ require "refinements/structs"
94
80
  ----
95
81
 
96
82
  === Using
@@ -106,9 +92,11 @@ class Example
106
92
  using Refinements::DateTimes
107
93
  using Refinements::Files
108
94
  using Refinements::Hashes
95
+ using Refinements::IOs
109
96
  using Refinements::Pathnames
110
97
  using Refinements::Strings
111
98
  using Refinements::StringIOs
99
+ using Refinements::Structs
112
100
  end
113
101
  ----
114
102
 
@@ -140,24 +128,47 @@ example.compress! # => ["An", "Example"]
140
128
  example # => ["An", "Example"]
141
129
  ----
142
130
 
143
- ===== #include
131
+ ===== #excluding
132
+
133
+ Removes given array or elements without mutating itself.
134
+
135
+ [source,ruby]
136
+ ----
137
+ [1, 2, 3, 4, 5].excluding [4, 5] # => [1, 2, 3]
138
+ [1, 2, 3, 4, 5].excluding 4, 5 # => [1, 2, 3]
139
+ ----
140
+
141
+ ===== #including
144
142
 
145
143
  Adds given array or elements without mutating itself.
146
144
 
147
145
  [source,ruby]
148
146
  ----
149
- [1, 2, 3].include [4, 5] # => [1, 2, 3, 4, 5]
150
- [1, 2, 3].include 4, 5 # => [1, 2, 3, 4, 5]
147
+ [1, 2, 3].including [4, 5] # => [1, 2, 3, 4, 5]
148
+ [1, 2, 3].including 4, 5 # => [1, 2, 3, 4, 5]
151
149
  ----
152
150
 
153
- ===== #exclude
151
+ ===== #intersperse
154
152
 
155
- Removes given array or elements without mutating itself.
153
+ Inserts additional elements or array between all members of given array.
154
+
155
+ [source,ruby]
156
+ ----
157
+ [1, 2, 3].intersperse :a # => [1, :a, 2, :a, 3]
158
+ [1, 2, 3].intersperse :a, :b # => [1, :a, :b, 2, :a, :b, 3]
159
+ [1, 2, 3].intersperse %i[a b c] # => [1, :a, :b, :c, 2, :a, :b, :c, 3]
160
+ ----
161
+
162
+ ===== #mean
163
+
164
+ Answers mean/average all elements within an array.
156
165
 
157
166
  [source,ruby]
158
167
  ----
159
- [1, 2, 3, 4, 5].exclude [4, 5] # => [1, 2, 3]
160
- [1, 2, 3, 4, 5].exclude 4, 5 # => [1, 2, 3]
168
+ [].mean # => 0
169
+ [5].mean # => 5
170
+ [1, 2, 3].mean # => 2
171
+ [1.25, 1.5, 1.75].mean # => 1.5
161
172
  ----
162
173
 
163
174
  ===== #ring
@@ -235,6 +246,72 @@ example = Hash.with_default []
235
246
  example[:b] # => []
236
247
  ----
237
248
 
249
+ ===== #deep_merge
250
+
251
+ Merges deeply nested hashes together without mutating itself.
252
+
253
+ [source,ruby]
254
+ ----
255
+ example = {a: "A", b: {one: "One", two: "Two"}}
256
+ example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
257
+ example # => {a: "A", b: {one: "One", two: "Two"}}
258
+ ----
259
+
260
+ ===== #deep_merge!
261
+
262
+ Merges deeply nested hashes together while mutating itself.
263
+
264
+ [source,ruby]
265
+ ----
266
+ example = {a: "A", b: {one: "One", two: "Two"}}
267
+ example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
268
+ example # => {a: "A", b: {one: 1, two: "Two"}}
269
+ ----
270
+
271
+ ===== #deep_stringify_keys
272
+
273
+ Stringifies keys of nested hash without mutating itself. Does not handle nested arrays, though.
274
+
275
+ [source,ruby]
276
+ ----
277
+ example = {a: {b: 2}}
278
+ example.deep_stringify_keys # => {"a" => {"b" => 1}}
279
+ example # => {a: {b: 2}}
280
+ ----
281
+
282
+ ===== #deep_stringify_keys!
283
+
284
+ Stringifies keys of nested hash while mutating itself. Does not handle nested arrays, though.
285
+
286
+ [source,ruby]
287
+ ----
288
+ example = {a: {b: 2}}
289
+ example.deep_stringify_keys! # => {"a" => {"b" => 1}}
290
+ example # => {"a" => {"b" => 1}}
291
+ ----
292
+
293
+ ===== #deep_symbolize_keys
294
+
295
+ Symbolizes keys of nested hash without mutating itself. Does not handle nested arrays, though.
296
+
297
+ [source,ruby]
298
+ ----
299
+ example = {"a" => {"b" => 2}}
300
+ example.deep_symbolize_keys # => {a: {b: 1}}
301
+ example # => {"a" => {"b" => 2}}
302
+ ----
303
+
304
+ ===== #deep_symbolize_keys!
305
+
306
+ Symbolizes keys of nested hash while mutating itself. Does not handle nested arrays, though.
307
+
308
+ [source,ruby]
309
+ ----
310
+ example = {"a" => {"b" => 2}}
311
+ example.deep_symbolize_keys! # => {a: {b: 1}}
312
+ example # => {a: {b: 1}}
313
+ ----
314
+
238
315
  ===== #except
239
316
 
240
317
  Answers new hash with given keys removed without mutating itself.
@@ -287,217 +364,216 @@ example.flatten_keys! # => {a_b: 1}
287
364
  example # => {a_b: 1}
288
365
  ----
289
366
 
290
- ===== #stringify_keys
367
+ ===== #recurse
291
368
 
292
- Converts keys to strings without mutating itself.
369
+ Recursively iterates over the hash and any hash value by applying the given block to it. Does not
370
+ handle nested arrays, though.
293
371
 
294
372
  [source,ruby]
295
373
  ----
296
- example = {a: 1, b: 2}
297
- example.stringify_keys # => {"a" => 1, "b" => 2}
298
- example # => {a: 1, b: 2}
374
+ example = {"a" => {"b" => 1}}
375
+ example.recurse(&:symbolize_keys) # => {a: {b: 1}}
376
+ example.recurse(&:invert) # => {{"b" => 1} => "a"}
299
377
  ----
300
378
 
301
- ===== #stringify_keys!
379
+ ===== #rekey
302
380
 
303
- Converts keys to strings while mutating itself.
381
+ Transforms keys per mapping (size of mapping can vary) without mutating itself.
304
382
 
305
383
  [source,ruby]
306
384
  ----
307
- example = {a: 1, b: 2}
308
- example.stringify_keys! # => {"a" => 1, "b" => 2}
309
- example # => {"a" => 1, "b" => 2}
385
+ example = {a: 1, b: 2, c: 3}
386
+ example.rekey a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
387
+ example # => {a: 1, b: 2, c: 3}
310
388
  ----
311
389
 
312
- ===== #symbolize_keys
390
+ ===== #rekey!
313
391
 
314
- Converts keys to symbols without mutating itself.
392
+ Transforms keys per mapping (size of mapping can vary) while mutating itself.
315
393
 
316
394
  [source,ruby]
317
395
  ----
318
- example = {"a" => 1, "b" => 2}
319
- example.symbolize_keys # => {a: 1, b: 2}
320
- example # => {"a" => 1, "b" => 2}
396
+ example = {a: 1, b: 2, c: 3}
397
+ example.rekey! a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
398
+ example # => {amber: 1, blue: 2, c: 3}
321
399
  ----
322
400
 
323
- ===== #symbolize_keys!
401
+ ===== #reverse_merge
324
402
 
325
- Converts keys to symbols while mutating itself.
403
+ Merges calling hash into passed in hash without mutating itself.
326
404
 
327
405
  [source,ruby]
328
406
  ----
329
- example = {"a" => 1, "b" => 2}
330
- example.symbolize_keys! # => {a: 1, b: 2}
331
- example # => {a: 1, b: 2}
407
+ example = {a: 1, b: 2}
408
+ example.reverse_merge a: 0, c: 3 # => {a: 1, b: 2, c: 3}
409
+ example # => {a: 1, b: 2}
332
410
  ----
333
411
 
334
- ===== #deep_merge
412
+ ===== #reverse_merge!
335
413
 
336
- Merges deeply nested hashes together without mutating itself.
414
+ Merges calling hash into passed in hash while mutating itself.
337
415
 
338
416
  [source,ruby]
339
417
  ----
340
- example = {a: "A", b: {one: "One", two: "Two"}}
341
- example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
342
- example # => {a: "A", b: {one: "One", two: "Two"}}
418
+ example = {a: 1, b: 2}
419
+ example.reverse_merge! a: 0, c: 3 # => {a: 1, b: 2, c: 3}
420
+ example # => {a: 1, b: 2, c: 3}
343
421
  ----
344
422
 
345
- ===== #deep_merge!
423
+ ===== #stringify_keys
346
424
 
347
- Merges deeply nested hashes together while mutating itself.
425
+ Converts keys to strings without mutating itself.
348
426
 
349
427
  [source,ruby]
350
428
  ----
351
- example = {a: "A", b: {one: "One", two: "Two"}}
352
- example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
353
- example # => {a: "A", b: {one: 1, two: "Two"}}
429
+ example = {a: 1, b: 2}
430
+ example.stringify_keys # => {"a" => 1, "b" => 2}
431
+ example # => {a: 1, b: 2}
354
432
  ----
355
433
 
356
- ===== #deep_stringify_keys
434
+ ===== #stringify_keys!
357
435
 
358
- Stringifies keys of nested hash without mutating itself. Does not handle nested arrays, though.
436
+ Converts keys to strings while mutating itself.
359
437
 
360
438
  [source,ruby]
361
439
  ----
362
- example = {a: {b: 2}}
363
- example.deep_stringify_keys # => {"a" => {"b" => 1}}
364
- example # => {a: {b: 2}}
440
+ example = {a: 1, b: 2}
441
+ example.stringify_keys! # => {"a" => 1, "b" => 2}
442
+ example # => {"a" => 1, "b" => 2}
365
443
  ----
366
444
 
367
- ===== #deep_stringify_keys!
445
+ ===== #symbolize_keys
368
446
 
369
- Stringifies keys of nested hash while mutating itself. Does not handle nested arrays, though.
447
+ Converts keys to symbols without mutating itself.
370
448
 
371
449
  [source,ruby]
372
450
  ----
373
- example = {a: {b: 2}}
374
- example.deep_stringify_keys! # => {"a" => {"b" => 1}}
375
- example # => {"a" => {"b" => 1}}
451
+ example = {"a" => 1, "b" => 2}
452
+ example.symbolize_keys # => {a: 1, b: 2}
453
+ example # => {"a" => 1, "b" => 2}
376
454
  ----
377
455
 
378
- ===== #deep_symbolize_keys
456
+ ===== #symbolize_keys!
379
457
 
380
- Symbolizes keys of nested hash without mutating itself. Does not handle nested arrays, though.
458
+ Converts keys to symbols while mutating itself.
381
459
 
382
460
  [source,ruby]
383
461
  ----
384
- example = {"a" => {"b" => 2}}
385
- example.deep_symbolize_keys # => {a: {b: 1}}
386
- example # => {"a" => {"b" => 2}}
462
+ example = {"a" => 1, "b" => 2}
463
+ example.symbolize_keys! # => {a: 1, b: 2}
464
+ example # => {a: 1, b: 2}
387
465
  ----
388
466
 
389
- ===== #deep_symbolize_keys!
467
+ ===== #use
390
468
 
391
- Symbolizes keys of nested hash while mutating itself. Does not handle nested arrays, though.
469
+ Passes each hash value as a block argument for further processing.
392
470
 
393
471
  [source,ruby]
394
472
  ----
395
- example = {"a" => {"b" => 2}}
396
- example.deep_symbolize_keys! # => {a: {b: 1}}
397
- example # => {a: {b: 1}}
473
+ example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
474
+ example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
398
475
  ----
399
476
 
400
- ===== #recurse
401
-
402
- Recursively iterates over the hash and any hash value by applying the given block to it. Does not
403
- handle nested arrays, though.
404
-
405
- [source,ruby]
406
- ----
407
- example = {"a" => {"b" => 1}}
408
- example.recurse(&:symbolize_keys) # => {a: {b: 1}}
409
- example.recurse(&:invert) # => {{"b" => 1} => "a"}
410
- ----
477
+ ==== IO
411
478
 
412
- ===== #rekey
479
+ ===== .void
413
480
 
414
- Transforms keys per mapping (size of mapping can vary) without mutating itself.
481
+ Answers an IO stream which points to `/dev/null` in order to ignore any reads or writes to the
482
+ stream. When given a block, the stream will automatically close upon block exit. When not given a
483
+ block, you'll need to close the stream manually.
415
484
 
416
485
  [source,ruby]
417
486
  ----
418
- example = {a: 1, b: 2, c: 3}
419
- example.rekey a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
420
- example # => {a: 1, b: 2, c: 3}
487
+ io = IO.void # => #<IO:fd 20>
488
+ io = IO.void { |void| void.write "nevermore" } # => #<IO:(closed)>
421
489
  ----
422
490
 
423
- ===== #rekey!
491
+ ===== #redirect
424
492
 
425
- Transforms keys per mapping (size of mapping can vary) while mutating itself.
493
+ Redirects current stream to other stream when given a block. Without a block, the original stream is
494
+ answered instead.
426
495
 
427
496
  [source,ruby]
428
497
  ----
429
- example = {a: 1, b: 2, c: 3}
430
- example.rekey! a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
431
- example # => {amber: 1, blue: 2, c: 3}
498
+ io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
499
+ other = IO.new IO.sysopen(Pathname("other.txt").to_s, "w+")
500
+
501
+ io.redirect other # => #<IO:fd 20>
502
+ io.redirect(other) { |stream| stream.write "test" } # => #<IO:fd 21>
432
503
  ----
433
504
 
434
- ===== #reverse_merge
505
+ ===== #reread
435
506
 
436
- Merges calling hash into passed in hash without mutating itself.
507
+ Answers full stream by rewinding to beginning of stream and reading all content.
437
508
 
438
509
  [source,ruby]
439
510
  ----
440
- example = {a: 1, b: 2}
441
- example.reverse_merge a: 0, c: 3 # => {a: 1, b: 2, c: 3}
442
- example # => {a: 1, b: 2}
443
- ----
444
-
445
- ===== #reverse_merge!
511
+ io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
512
+ io.write "This is a test."
446
513
 
447
- Merges calling hash into passed in hash while mutating itself.
514
+ io.reread # => "This is a test."
515
+ io.reread 4 # => "This"
448
516
 
449
- [source,ruby]
450
- ----
451
- example = {a: 1, b: 2}
452
- example.reverse_merge! a: 0, c: 3 # => {a: 1, b: 2, c: 3}
453
- example # => {a: 1, b: 2, c: 3}
517
+ buffer = "".dup
518
+ io.reread(buffer: buffer) # => "This is a test."
519
+ buffer # => "This is a test."
454
520
  ----
455
521
 
456
- ===== #use
522
+ ===== #squelch
457
523
 
458
- Passes each hash value as a block argument for further processing.
524
+ Temporarily ignores any reads/writes for code executed within a block. Answers itself without any
525
+ arguments or when given a block.
459
526
 
460
527
  [source,ruby]
461
528
  ----
462
- example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
463
- example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
529
+ io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
530
+ io.squelch # => #<IO:fd 20>
531
+ io.squelch { io.write "Test" } # => #<IO:fd 20>
532
+ io.reread # => ""
464
533
  ----
465
534
 
466
535
  ==== Pathname
467
536
 
468
537
  ===== Pathname
469
538
 
470
- Enhances the conversion function -- refined from `Kernel` -- which casts `nil` into a pathname in
471
- order to avoid: `TypeError (no implicit conversion of nil into String)`. The pathname is still
472
- invalid but at least you have an instance of `Pathname`, which behaves like a _Null Object_, that
473
- can still be used to construct a valid path.
539
+ Enhances the `Kernel` conversion function which casts `nil` into a pathname in order to avoid:
540
+ `TypeError (no implicit conversion of nil into String)`. The pathname remains invalid but at least
541
+ you have an instance of `Pathname`, which behaves like a _Null Object_, that can be used to
542
+ construct a valid path.
474
543
 
475
544
  [source,ruby]
476
545
  ----
477
546
  Pathname(nil) # => Pathname("")
478
547
  ----
479
548
 
480
- ===== #name
549
+ ===== #change_dir
481
550
 
482
- Answers file name without extension.
551
+ Inherits and wraps `Dir.chdir` behavior by changing to directory of current path. See
552
+ link:https://rubyapi.org/2.7/o/s?q=Dir.chdir[Dir.chdir] for details.
483
553
 
484
554
  [source,ruby]
485
555
  ----
486
- Pathname("example.txt").name # => Pathname("example")
556
+ Pathname.pwd # => "/"
557
+ Pathname("/test").make_dir.change_dir # => Pathname "/test"
558
+ Pathname.pwd # => "/test"
559
+
560
+ Pathname.pwd # => "/"
561
+ Pathname("/test").make_dir.change_dir { "example" } # => "example"
562
+ Pathname.pwd # => "/"
487
563
  ----
488
564
 
489
565
  ===== #copy
490
566
 
491
- Copies file from current location to new location.
567
+ Copies file from current location to new location while answering itself so it can be chained.
492
568
 
493
569
  [source,ruby]
494
570
  ----
495
- Pathname("input.txt").copy Pathname("output.txt")
571
+ Pathname("input.txt").copy Pathname("output.txt") # => Pathname("input.txt")
496
572
  ----
497
573
 
498
574
  ===== #directories
499
575
 
500
- Answers all or filtered directories for current path.
576
+ Answers all directories or filtered directories for current path.
501
577
 
502
578
  [source,ruby]
503
579
  ----
@@ -517,7 +593,7 @@ Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
517
593
 
518
594
  ===== #files
519
595
 
520
- Answers all or filtered files for current path.
596
+ Answers all files or filtered files for current path.
521
597
 
522
598
  [source,ruby]
523
599
  ----
@@ -539,6 +615,48 @@ Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test")
539
615
  # => Pathname("/test/some/test")
540
616
  ----
541
617
 
618
+ ===== #make_ancestors
619
+
620
+ Ensures all ancestor directories are created for a path.
621
+
622
+ [source,ruby]
623
+ ----
624
+ Pathname("/one/two").make_ancestors # => Pathname("/one/two")
625
+ Pathname("/one").exist? # => true
626
+ Pathname("/one/two").exist? # => false
627
+ ----
628
+
629
+ ===== #make_dir
630
+
631
+ Provides alternative `#mkdir` behavior by always answering itself (even when directory exists) and
632
+ not throwing errors when directory does exist in order to ensure the pathname can be chained.
633
+
634
+ [source,ruby]
635
+ ----
636
+ Pathname("/one").make_dir # => Pathname("/one")
637
+ Pathname("/one").make_dir.make_dir # => Pathname("/one")
638
+ ----
639
+
640
+ ===== #make_path
641
+
642
+ Provides alternative `#mkpath` behavior by always answering itself (even when full path exists) and
643
+ not throwing errors when directory does exist in order to ensure the pathname can be chained.
644
+
645
+ [source,ruby]
646
+ ----
647
+ Pathname("/one/two/three").make_path # => Pathname("/one/two/three")
648
+ Pathname("/one/two/three").make_path.make_path # => Pathname("/one/two/three")
649
+ ----
650
+
651
+ ===== #name
652
+
653
+ Answers file name without extension.
654
+
655
+ [source,ruby]
656
+ ----
657
+ Pathname("example.txt").name # => Pathname("example")
658
+ ----
659
+
542
660
  ===== #relative_parent
543
661
 
544
662
  Answers relative path from parent directory. This is a complement to `#relative_path_from`.
@@ -548,59 +666,74 @@ Answers relative path from parent directory. This is a complement to `#relative_
548
666
  Pathname("/one/two/three").relative_parent("/one") # => Pathname "two"
549
667
  ----
550
668
 
551
- ===== #make_ancestors
669
+ ===== #remove_dir
552
670
 
553
- Ensures all ancestor directories are created for a path.
671
+ Provides alternative `#rmdir` behavior by always answering itself (even when full path exists) and
672
+ not throwing errors when directory does exist in order to ensure the pathname can be chained.
554
673
 
555
674
  [source,ruby]
556
675
  ----
557
- Pathname("/one/two").make_ancestors
558
- Pathname("/one").exist? # => true
559
- Pathname("/one/two").exist? # => false
676
+ Pathname("/test").make_dir.remove_dir.exist? # => false
677
+ Pathname("/test").remove_dir # => Pathname("/test")
678
+ Pathname("/test").remove_dir.remove_dir # => Pathname("/test")
560
679
  ----
561
680
 
562
- ===== #rewrite
681
+ ===== #remove_tree
563
682
 
564
- When given a block, it provides the contents of the recently read file for manipulation and
565
- immediate writing back to the same file.
683
+ Provides alternative `#rmtree` behavior by always answering itself (even when full path exists) and
684
+ not throwing errors when directory does exist in order to ensure the pathname can be chained.
566
685
 
567
686
  [source,ruby]
568
687
  ----
569
- Pathname("/test.txt").rewrite { |content| content.sub "[placeholder]", "example" }
688
+ parent_path = Pathname "/one"
689
+ child_path = parent_path.join "two"
690
+
691
+ child_path.make_path
692
+ child_path.remove_tree # => Pathname "/one/two"
693
+ child_path.exist? # => false
694
+ paremt_path.exist? # => true
695
+
696
+ child_path.make_path
697
+ parent_path.remove_tree # => Pathname "/one"
698
+ child_path.exist? # => false
699
+ parent_path.exist? # => false
570
700
  ----
571
701
 
572
- ===== #touch
702
+ ===== #rewrite
573
703
 
574
- Updates access and modification times for path. Defaults to current time.
704
+ When given a block, it provides the contents of the recently read file for manipulation and
705
+ immediate writing back to the same file.
575
706
 
576
707
  [source,ruby]
577
708
  ----
578
- Pathname("example.txt").touch
579
- Pathname("example.txt").touch at: Time.now - 1
709
+ Pathname("/test.txt").rewrite # => Pathname("/test.txt")
710
+ Pathname("/test.txt").rewrite { |body| body.sub "[token]", "example" } # => Pathname("/test.txt")
580
711
  ----
581
712
 
582
- ==== String
583
-
584
- ===== #first
713
+ ===== #touch
585
714
 
586
- Answers first character of a string or first set of characters if given a number.
715
+ Updates access and modification times for path. Defaults to current time.
587
716
 
588
717
  [source,ruby]
589
718
  ----
590
- "example".first # => "e"
591
- "example".first 4 # => "exam"
719
+ Pathname("example.txt").touch # => Pathname("example.txt")
720
+ Pathname("example.txt").touch at: Time.now - 1 # => Pathname("example.txt")
592
721
  ----
593
722
 
594
- ===== #last
723
+ ===== #write
595
724
 
596
- Answers last character of a string or last set of characters if given a number.
725
+ Writes to file and answers itself so it can be chained. See `IO.write` for details on additional
726
+ options.
597
727
 
598
728
  [source,ruby]
599
729
  ----
600
- "instant".last # => "t"
601
- "instant".last 3 # => "ant"
730
+ Pathname("example.txt").write "test" # => Pathname("example.txt")
731
+ Pathname("example.txt").write "test", offset: 1 # => Pathname("example.txt")
732
+ Pathname("example.txt").write "test", mode: "a" # => Pathname("example.txt")
602
733
  ----
603
734
 
735
+ ==== String
736
+
604
737
  ===== #blank?
605
738
 
606
739
  Answers `true`/`false` based on whether string is blank, `<space>`, `\n`, `\t`, and/or `\r`.
@@ -610,13 +743,13 @@ Answers `true`/`false` based on whether string is blank, `<space>`, `\n`, `\t`,
610
743
  " \n\t\r".blank? # => true
611
744
  ----
612
745
 
613
- ===== #up
746
+ ===== #camelcase
614
747
 
615
- Answers string with only first letter upcased.
748
+ Answers a camelcased string.
616
749
 
617
750
  [source,ruby]
618
751
  ----
619
- "example".up # => "Example"
752
+ "this_is_an_example".camelcase # => "ThisIsAnExample"
620
753
  ----
621
754
 
622
755
  ===== #down
@@ -628,6 +761,16 @@ Answers string with only first letter downcased.
628
761
  "EXAMPLE".down # => "eXAMPLE"
629
762
  ----
630
763
 
764
+ ===== #first
765
+
766
+ Answers first character of a string or first set of characters if given a number.
767
+
768
+ [source,ruby]
769
+ ----
770
+ "example".first # => "e"
771
+ "example".first 4 # => "exam"
772
+ ----
773
+
631
774
  ===== #indent
632
775
 
633
776
  Answers string indented by two spaces by default.
@@ -641,13 +784,14 @@ Answers string indented by two spaces by default.
641
784
  "example".indent 3, padding: " " # => " example"
642
785
  ----
643
786
 
644
- ===== #camelcase
787
+ ===== #last
645
788
 
646
- Answers a camelcased string.
789
+ Answers last character of a string or last set of characters if given a number.
647
790
 
648
791
  [source,ruby]
649
792
  ----
650
- "this_is_an_example".camelcase # => "ThisIsAnExample"
793
+ "instant".last # => "t"
794
+ "instant".last 3 # => "ant"
651
795
  ----
652
796
 
653
797
  ===== #snakecase
@@ -681,6 +825,15 @@ Answers string as a boolean.
681
825
  "example".to_bool # => false
682
826
  ----
683
827
 
828
+ ===== #up
829
+
830
+ Answers string with only first letter upcased.
831
+
832
+ [source,ruby]
833
+ ----
834
+ "example".up # => "Example"
835
+ ----
836
+
684
837
  ==== String IO
685
838
 
686
839
  ===== #reread
@@ -696,8 +849,70 @@ io.reread # => "This is a test."
696
849
  io.reread 4 # => "This"
697
850
 
698
851
  buffer = "".dup
699
- io.reread(buffer: buffer)
700
- buffer # => "This is a test."
852
+ io.reread(buffer: buffer) # => "This is a test."
853
+ buffer # => "This is a test."
854
+ ----
855
+
856
+ ==== Struct
857
+
858
+ ===== #merge
859
+
860
+ Merges multiple attributes without mutating itself.
861
+
862
+ [source,ruby]
863
+ ----
864
+ Example = Struct.new :a, :b, :c
865
+ example = Example[1, 2, 3]
866
+ example.merge a: 10 # => #<struct a=10, b=2, c=3>
867
+ example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
868
+ example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
869
+ example # => #<struct a=1, b=2, c=3>
870
+
871
+ Example = Struct.new :a, :b, :c, keyword_init: true
872
+ example = Example[a: 1, b: 2, c: 3]
873
+ example.merge a: 10 # => #<struct a=10, b=2, c=3>
874
+ example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
875
+ example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
876
+ example # => #<struct a=1, b=2, c=3>
877
+ ----
878
+
879
+ ===== #merge!
880
+
881
+ Merges multiple attributes while mutating itself.
882
+
883
+ [source,ruby]
884
+ ----
885
+ Example = Struct.new :a, :b, :c
886
+ example = Example[1, 2, 3]
887
+ example.merge! a: 10 # => #<struct a=10, b=2, c=3>
888
+ example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
889
+ example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
890
+ example # => #<struct a=10, b=20, c=30>
891
+
892
+ Example = Struct.new :a, :b, :c, keyword_init: true
893
+ example = Example[a: 1, b: 2, c: 3]
894
+ example.merge! a: 10 # => #<struct a=10, b=2, c=3>
895
+ example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
896
+ example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
897
+ example # => #<struct a=10, b=20, c=30>
898
+ ----
899
+
900
+ == Development
901
+
902
+ To contribute, run:
903
+
904
+ [source,bash]
905
+ ----
906
+ git clone https://github.com/bkuhlmann/refinements.git
907
+ cd refinements
908
+ bin/setup
909
+ ----
910
+
911
+ You can also use the IRB console for direct access to all objects:
912
+
913
+ [source,bash]
914
+ ----
915
+ bin/console
701
916
  ----
702
917
 
703
918
  == Tests