refinements 8.3.0 → 8.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.adoc CHANGED
@@ -11,9 +11,12 @@ image::https://img.shields.io/badge/code_style-alchemists-brightgreen.svg[Alchem
11
11
  [link=https://circleci.com/gh/bkuhlmann/refinements]
12
12
  image::https://circleci.com/gh/bkuhlmann/refinements.svg?style=svg[Circle CI Status]
13
13
 
14
- Refinements is a collection of enhancements to primitive Ruby objects without needing to resort
15
- painful and hard to debug monkey patches. These refinements give you additional syntactic sugar to
16
- build clean and concise implementations all while using less code.
14
+ Refinements are a collection of enhancements to primitive Ruby objects without needing to resort to
15
+ painful and hard to debug
16
+ link:https://www.alchemists.io/articles/ruby_antipatterns/#_monkey_patches[monkey patches]. These
17
+ refinements give you additional syntactic sugar to develop clean and concise implementations while
18
+ using less code. By refining our code we can acquire the functionality we wish the core primitives
19
+ had!
17
20
 
18
21
  toc::[]
19
22
 
@@ -70,6 +73,7 @@ gem "refinements", require: false
70
73
  ----
71
74
  require "refinements/arrays"
72
75
  require "refinements/big_decimals"
76
+ require "refinements/classes"
73
77
  require "refinements/date_times"
74
78
  require "refinements/hashes"
75
79
  require "refinements/ios"
@@ -77,6 +81,7 @@ require "refinements/pathnames"
77
81
  require "refinements/strings"
78
82
  require "refinements/string_ios"
79
83
  require "refinements/structs"
84
+ require "refinements/symbols"
80
85
  ----
81
86
 
82
87
  === Using
@@ -89,6 +94,7 @@ refinement(s):
89
94
  class Example
90
95
  using Refinements::Arrays
91
96
  using Refinements::BigDecimals
97
+ using Refinements::Classes
92
98
  using Refinements::DateTimes
93
99
  using Refinements::Hashes
94
100
  using Refinements::IOs
@@ -96,6 +102,7 @@ class Example
96
102
  using Refinements::Strings
97
103
  using Refinements::StringIOs
98
104
  using Refinements::Structs
105
+ using Refinements::Symbols
99
106
  end
100
107
  ----
101
108
 
@@ -107,13 +114,15 @@ The following sections demonstrate how each refinement enriches your objects wit
107
114
 
108
115
  ===== #compress
109
116
 
110
- Removes `nil` and empty values without mutating itself.
117
+ Removes `nil` and empty objects without mutating itself.
111
118
 
112
119
  [source,ruby]
113
120
  ----
114
- example = ["An", nil, "", "Example"]
115
- example.compress # => ["An", "Example"]
116
- example # => ["An", nil, "", "Example"]
121
+ object = Object.new
122
+ example = [1, "blueberry", nil, "", [], {}, object]
123
+
124
+ example.compress # [1, "blueberry", object]
125
+ example # [1, "blueberry", nil, "", [], {}, object]
117
126
  ----
118
127
 
119
128
  ===== #compress!
@@ -122,9 +131,11 @@ Removes `nil` and empty values while mutating itself.
122
131
 
123
132
  [source,ruby]
124
133
  ----
125
- example = ["An", nil, "", "Example"]
126
- example.compress! # => ["An", "Example"]
127
- example # => ["An", "Example"]
134
+ object = Object.new
135
+ example = [1, "blueberry", nil, "", [], {}, object]
136
+
137
+ example.compress # [1, "blueberry", object]
138
+ example # [1, "blueberry", object]
128
139
  ----
129
140
 
130
141
  ===== #excluding
@@ -133,8 +144,8 @@ Removes given array or elements without mutating itself.
133
144
 
134
145
  [source,ruby]
135
146
  ----
136
- [1, 2, 3, 4, 5].excluding [4, 5] # => [1, 2, 3]
137
- [1, 2, 3, 4, 5].excluding 4, 5 # => [1, 2, 3]
147
+ [1, 2, 3, 4, 5].excluding [4, 5] # [1, 2, 3]
148
+ [1, 2, 3, 4, 5].excluding 4, 5 # [1, 2, 3]
138
149
  ----
139
150
 
140
151
  ===== #filter_find
@@ -149,9 +160,9 @@ handlers = [
149
160
  ->(object) { object if object == :a }
150
161
  ]
151
162
 
152
- handlers.filter_find # => Enumerator::Lazy
153
- handlers.filter_find { |handler| handler.call :a } # => :a
154
- handlers.filter_find { |handler| handler.call :x } # => nil
163
+ handlers.filter_find # Enumerator::Lazy
164
+ handlers.filter_find { |handler| handler.call :a } # :a
165
+ handlers.filter_find { |handler| handler.call :x } # nil
155
166
  ----
156
167
 
157
168
  ===== #including
@@ -160,8 +171,8 @@ Adds given array or elements without mutating itself.
160
171
 
161
172
  [source,ruby]
162
173
  ----
163
- [1, 2, 3].including [4, 5] # => [1, 2, 3, 4, 5]
164
- [1, 2, 3].including 4, 5 # => [1, 2, 3, 4, 5]
174
+ [1, 2, 3].including [4, 5] # [1, 2, 3, 4, 5]
175
+ [1, 2, 3].including 4, 5 # [1, 2, 3, 4, 5]
165
176
  ----
166
177
 
167
178
  ===== #intersperse
@@ -170,9 +181,9 @@ Inserts additional elements or array between all members of given array.
170
181
 
171
182
  [source,ruby]
172
183
  ----
173
- [1, 2, 3].intersperse :a # => [1, :a, 2, :a, 3]
174
- [1, 2, 3].intersperse :a, :b # => [1, :a, :b, 2, :a, :b, 3]
175
- [1, 2, 3].intersperse %i[a b c] # => [1, :a, :b, :c, 2, :a, :b, :c, 3]
184
+ [1, 2, 3].intersperse :a # [1, :a, 2, :a, 3]
185
+ [1, 2, 3].intersperse :a, :b # [1, :a, :b, 2, :a, :b, 3]
186
+ [1, 2, 3].intersperse %i[a b c] # [1, :a, :b, :c, 2, :a, :b, :c, 3]
176
187
  ----
177
188
 
178
189
  ===== #maximum
@@ -184,8 +195,8 @@ Answers the maximum extracted value from a collection of objects.
184
195
  Point = Struct.new :x, :y, keyword_init: true
185
196
  points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
186
197
 
187
- points.maximum(:x) # => 2
188
- points.maximum(:y) # => 3
198
+ points.maximum(:x) # 2
199
+ points.maximum(:y) # 3
189
200
  ----
190
201
 
191
202
  ===== #mean
@@ -194,10 +205,10 @@ Answers mean/average all elements within an array.
194
205
 
195
206
  [source,ruby]
196
207
  ----
197
- [].mean # => 0
198
- [5].mean # => 5
199
- [1, 2, 3].mean # => 2
200
- [1.25, 1.5, 1.75].mean # => 1.5
208
+ [].mean # 0
209
+ [5].mean # 5
210
+ [1, 2, 3].mean # 2
211
+ [1.25, 1.5, 1.75].mean # 1.5
201
212
  ----
202
213
 
203
214
  ===== #minimum
@@ -209,8 +220,8 @@ Answers the minimum extracted value from a collection of objects.
209
220
  Point = Struct.new :x, :y, keyword_init: true
210
221
  points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
211
222
 
212
- points.minimum(:x) # => 0
213
- points.minimum(:y) # => 1
223
+ points.minimum(:x) # 0
224
+ points.minimum(:y) # 1
214
225
  ----
215
226
 
216
227
  ===== #pad
@@ -220,9 +231,9 @@ needs to be a specific size with padded values.
220
231
 
221
232
  [source,ruby]
222
233
  ----
223
- [1].pad 0 # => [1]
224
- [1].pad 0, max: 3 # => [1, 0, 0]
225
- [1, 2].pad 3, max: 3 # => [1, 2, 3]
234
+ [1].pad 0 # [1]
235
+ [1].pad 0, max: 3 # [1, 0, 0]
236
+ [1, 2].pad 3, max: 3 # [1, 2, 3]
226
237
  ----
227
238
 
228
239
  ===== #ring
@@ -232,7 +243,7 @@ Answers a circular array which can enumerate before, current, after elements.
232
243
  [source,ruby]
233
244
  ----
234
245
  example = [1, 2, 3]
235
- example.ring # => #<Enumerator: ...>
246
+ example.ring # "#<Enumerator: ...>"
236
247
  example.ring { |(before, current, after)| puts "#{before} #{current} #{after}" }
237
248
 
238
249
  # [3 1 2]
@@ -248,7 +259,23 @@ Allows one to inspect a big decimal with numeric representation.
248
259
 
249
260
  [source,ruby]
250
261
  ----
251
- BigDecimal.new("5.0E-10").inspect # => "#<BigDecimal:3fd3d458fe84 0.0000000005>"
262
+ BigDecimal.new("5.0E-10").inspect # "#<BigDecimal:3fd3d458fe84 0.0000000005>"
263
+ ----
264
+
265
+ ==== Class
266
+
267
+ ===== #descendants
268
+
269
+ Answers descendants of a class.
270
+
271
+ [source,ruby]
272
+ ----
273
+ a = Class.new
274
+ b = Class.new a
275
+ c = Class.new a
276
+
277
+ a.descendants # [b, c]
278
+ Class.new.descendants # []
252
279
  ----
253
280
 
254
281
  ==== DateTime
@@ -259,7 +286,7 @@ Answers new DateTime object for current UTC date/time.
259
286
 
260
287
  [source,ruby]
261
288
  ----
262
- DateTime.utc # => #<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867000n),+0s,2299161j)>
289
+ DateTime.utc # "#<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867000n),+0s,2299161j)>"
263
290
  ----
264
291
 
265
292
  ==== Hash
@@ -271,8 +298,8 @@ Answers new hash where missing keys, even deeply nested, answer an empty hash.
271
298
  [source,ruby]
272
299
  ----
273
300
  example = Hash.infinite
274
- example[:a] # => {}
275
- example[:a][:b][:c] # => {}
301
+ example[:a] # {}
302
+ example[:a][:b][:c] # {}
276
303
  ----
277
304
 
278
305
  ===== .with_default
@@ -282,34 +309,36 @@ Answers new hash where every top-level missing key has the same default value.
282
309
  [source,ruby]
283
310
  ----
284
311
  example = Hash.with_default ""
285
- example[:a] # => ""
312
+ example[:a] # ""
286
313
 
287
314
  example = Hash.with_default []
288
- example[:b] # => []
315
+ example[:b] # []
289
316
  ----
290
317
 
291
318
  ===== #compress
292
319
 
293
- Removes empty objects without mutating itself.
320
+ Removes `nil` and empty objects without mutating itself.
294
321
 
295
322
  [source,ruby]
296
323
  ----
297
324
  object = Object.new
298
325
  example = {a: 1, b: "blueberry", c: nil, d: "", e: [], f: {}, g: object}
299
- example.compress # => {a: 1, b: "blueberry", g: object}
300
- example # => {a: 1, b: "blueberry", c: nil, d: "", e: [], f: {}, g: object}
326
+
327
+ example.compress # {a: 1, b: "blueberry", g: object}
328
+ example # {a: 1, b: "blueberry", c: nil, d: "", e: [], f: {}, g: object}
301
329
  ----
302
330
 
303
331
  ===== #compress!
304
332
 
305
- Removes empty objects while mutating itself.
333
+ Removes `nil` and empty objects while mutating itself.
306
334
 
307
335
  [source,ruby]
308
336
  ----
309
337
  object = Object.new
310
338
  example = {a: 1, b: "blueberry", c: nil, d: "", e: [], f: {}, g: object}
311
- example.compress! # => {a: 1, b: "blueberry", g: object}
312
- example # => {a: 1, b: "blueberry", g: object}
339
+
340
+ example.compress! # {a: 1, b: "blueberry", g: object}
341
+ example # {a: 1, b: "blueberry", g: object}
313
342
  ----
314
343
 
315
344
  ===== #deep_merge
@@ -319,8 +348,9 @@ Merges deeply nested hashes together without mutating itself.
319
348
  [source,ruby]
320
349
  ----
321
350
  example = {a: "A", b: {one: "One", two: "Two"}}
322
- example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
323
- example # => {a: "A", b: {one: "One", two: "Two"}}
351
+
352
+ example.deep_merge b: {one: 1} # {a: "A", b: {one: 1, two: "Two"}}
353
+ example # {a: "A", b: {one: "One", two: "Two"}}
324
354
  ----
325
355
 
326
356
  ===== #deep_merge!
@@ -330,8 +360,9 @@ Merges deeply nested hashes together while mutating itself.
330
360
  [source,ruby]
331
361
  ----
332
362
  example = {a: "A", b: {one: "One", two: "Two"}}
333
- example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
334
- example # => {a: "A", b: {one: 1, two: "Two"}}
363
+
364
+ example.deep_merge! b: {one: 1} # {a: "A", b: {one: 1, two: "Two"}}
365
+ example # {a: "A", b: {one: 1, two: "Two"}}
335
366
  ----
336
367
 
337
368
  ===== #deep_stringify_keys
@@ -341,8 +372,8 @@ Stringifies keys of nested hash without mutating itself. Does not handle nested
341
372
  [source,ruby]
342
373
  ----
343
374
  example = {a: {b: 2}}
344
- example.deep_stringify_keys # => {"a" => {"b" => 1}}
345
- example # => {a: {b: 2}}
375
+ example.deep_stringify_keys # {"a" => {"b" => 1}}
376
+ example # {a: {b: 2}}
346
377
  ----
347
378
 
348
379
  ===== #deep_stringify_keys!
@@ -352,8 +383,8 @@ Stringifies keys of nested hash while mutating itself. Does not handle nested ar
352
383
  [source,ruby]
353
384
  ----
354
385
  example = {a: {b: 2}}
355
- example.deep_stringify_keys! # => {"a" => {"b" => 1}}
356
- example # => {"a" => {"b" => 1}}
386
+ example.deep_stringify_keys! # {"a" => {"b" => 1}}
387
+ example # {"a" => {"b" => 1}}
357
388
  ----
358
389
 
359
390
  ===== #deep_symbolize_keys
@@ -363,8 +394,8 @@ Symbolizes keys of nested hash without mutating itself. Does not handle nested a
363
394
  [source,ruby]
364
395
  ----
365
396
  example = {"a" => {"b" => 2}}
366
- example.deep_symbolize_keys # => {a: {b: 1}}
367
- example # => {"a" => {"b" => 2}}
397
+ example.deep_symbolize_keys # {a: {b: 1}}
398
+ example # {"a" => {"b" => 2}}
368
399
  ----
369
400
 
370
401
  ===== #deep_symbolize_keys!
@@ -374,8 +405,24 @@ Symbolizes keys of nested hash while mutating itself. Does not handle nested arr
374
405
  [source,ruby]
375
406
  ----
376
407
  example = {"a" => {"b" => 2}}
377
- example.deep_symbolize_keys! # => {a: {b: 1}}
378
- example # => {a: {b: 1}}
408
+ example.deep_symbolize_keys! # {a: {b: 1}}
409
+ example # {a: {b: 1}}
410
+ ----
411
+
412
+ ===== #fetch_value
413
+
414
+ Fetches value for exiting or missing key. Behavior is identical to `#fetch` except when the value of
415
+ the key is `nil` you'll get the default value instead. This eliminates the need for using an _or_
416
+ expression `example.fetch(:desired_key) || "default_value"`.
417
+
418
+ [source,ruby]
419
+ ----
420
+ {a: "test"}.fetch_value :a, "default" # "test"
421
+ {a: "test"}.fetch_value :a # "test"
422
+ {a: nil}.fetch_value :a, "default" # "default"
423
+ {}.fetch_value(:a) { "default" } # "default"
424
+ {}.fetch_value :a # KeyError
425
+ {a: "test"}.fetch_value # ArgumentError
379
426
  ----
380
427
 
381
428
  ===== #flatten_keys
@@ -385,15 +432,15 @@ though.
385
432
 
386
433
  [source,ruby]
387
434
  ----
388
- {a: {b: 1}}.flatten_keys prefix: :test # => {test_a_b: 1}
389
- {a: {b: 1}}.flatten_keys delimiter: :| # => {:"a|b" => 1}
435
+ {a: {b: 1}}.flatten_keys prefix: :test # {test_a_b: 1}
436
+ {a: {b: 1}}.flatten_keys delimiter: :| # {:"a|b" => 1}
390
437
 
391
- {a: {b: 1}}.flatten_keys cast: :to_s # => {"a_b" => 1}
392
- {"a" => {"b" => 1}}.flatten_keys cast: :to_sym # => {a_b: 1}
438
+ {a: {b: 1}}.flatten_keys cast: :to_s # {"a_b" => 1}
439
+ {"a" => {"b" => 1}}.flatten_keys cast: :to_sym # {a_b: 1}
393
440
 
394
441
  example = {a: {b: 1}}
395
- example.flatten_keys # => {a_b: 1}
396
- example # => {a: {b: 1}}
442
+ example.flatten_keys # {a_b: 1}
443
+ example # {a: {b: 1}}
397
444
  ----
398
445
 
399
446
  ===== #flatten_keys!
@@ -404,8 +451,8 @@ though.
404
451
  [source,ruby]
405
452
  ----
406
453
  example = {a: {b: 1}}
407
- example.flatten_keys! # => {a_b: 1}
408
- example # => {a_b: 1}
454
+ example.flatten_keys! # {a_b: 1}
455
+ example # {a_b: 1}
409
456
  ----
410
457
 
411
458
  ===== #recurse
@@ -416,8 +463,8 @@ handle nested arrays, though.
416
463
  [source,ruby]
417
464
  ----
418
465
  example = {"a" => {"b" => 1}}
419
- example.recurse(&:symbolize_keys) # => {a: {b: 1}}
420
- example.recurse(&:invert) # => {{"b" => 1} => "a"}
466
+ example.recurse(&:symbolize_keys) # {a: {b: 1}}
467
+ example.recurse(&:invert) # {{"b" => 1} => "a"}
421
468
  ----
422
469
 
423
470
  ===== #stringify_keys
@@ -427,8 +474,8 @@ Converts keys to strings without mutating itself.
427
474
  [source,ruby]
428
475
  ----
429
476
  example = {a: 1, b: 2}
430
- example.stringify_keys # => {"a" => 1, "b" => 2}
431
- example # => {a: 1, b: 2}
477
+ example.stringify_keys # {"a" => 1, "b" => 2}
478
+ example # {a: 1, b: 2}
432
479
  ----
433
480
 
434
481
  ===== #stringify_keys!
@@ -438,8 +485,8 @@ Converts keys to strings while mutating itself.
438
485
  [source,ruby]
439
486
  ----
440
487
  example = {a: 1, b: 2}
441
- example.stringify_keys! # => {"a" => 1, "b" => 2}
442
- example # => {"a" => 1, "b" => 2}
488
+ example.stringify_keys! # {"a" => 1, "b" => 2}
489
+ example # {"a" => 1, "b" => 2}
443
490
  ----
444
491
 
445
492
  ===== #symbolize_keys
@@ -449,8 +496,8 @@ Converts keys to symbols without mutating itself.
449
496
  [source,ruby]
450
497
  ----
451
498
  example = {"a" => 1, "b" => 2}
452
- example.symbolize_keys # => {a: 1, b: 2}
453
- example # => {"a" => 1, "b" => 2}
499
+ example.symbolize_keys # {a: 1, b: 2}
500
+ example # {"a" => 1, "b" => 2}
454
501
  ----
455
502
 
456
503
  ===== #symbolize_keys!
@@ -460,8 +507,8 @@ Converts keys to symbols while mutating itself.
460
507
  [source,ruby]
461
508
  ----
462
509
  example = {"a" => 1, "b" => 2}
463
- example.symbolize_keys! # => {a: 1, b: 2}
464
- example # => {a: 1, b: 2}
510
+ example.symbolize_keys! # {a: 1, b: 2}
511
+ example # {a: 1, b: 2}
465
512
  ----
466
513
 
467
514
  ===== #use
@@ -471,7 +518,8 @@ Passes each hash value as a block argument for further processing.
471
518
  [source,ruby]
472
519
  ----
473
520
  example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
474
- example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
521
+
522
+ example.use { |unit, street| "#{unit} #{street}" } # "221B Baker Street"
475
523
  ----
476
524
 
477
525
  ==== IO
@@ -484,8 +532,8 @@ block, you'll need to close the stream manually.
484
532
 
485
533
  [source,ruby]
486
534
  ----
487
- io = IO.void # => #<IO:fd 20>
488
- io = IO.void { |void| void.write "nevermore" } # => #<IO:(closed)>
535
+ io = IO.void # "#<IO:fd 20>"
536
+ io = IO.void { |void| void.write "nevermore" } # "#<IO:(closed)>"
489
537
  ----
490
538
 
491
539
  ===== #redirect
@@ -498,8 +546,8 @@ answered instead.
498
546
  io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
499
547
  other = IO.new IO.sysopen(Pathname("other.txt").to_s, "w+")
500
548
 
501
- io.redirect other # => #<IO:fd 20>
502
- io.redirect(other) { |stream| stream.write "test" } # => #<IO:fd 21>
549
+ io.redirect other # "#<IO:fd 20>"
550
+ io.redirect(other) { |stream| stream.write "test" } # "#<IO:fd 21>"
503
551
  ----
504
552
 
505
553
  ===== #reread
@@ -511,12 +559,12 @@ Answers full stream by rewinding to beginning of stream and reading all content.
511
559
  io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
512
560
  io.write "This is a test."
513
561
 
514
- io.reread # => "This is a test."
515
- io.reread 4 # => "This"
562
+ io.reread # "This is a test."
563
+ io.reread 4 # "This"
516
564
 
517
565
  buffer = "".dup
518
- io.reread(buffer: buffer) # => "This is a test."
519
- buffer # => "This is a test."
566
+ io.reread(buffer: buffer) # "This is a test."
567
+ buffer # "This is a test."
520
568
  ----
521
569
 
522
570
  ===== #squelch
@@ -527,9 +575,10 @@ arguments or when given a block.
527
575
  [source,ruby]
528
576
  ----
529
577
  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 # => ""
578
+
579
+ io.squelch # "#<IO:fd 20>"
580
+ io.squelch { io.write "Test" } # "#<IO:fd 20>"
581
+ io.reread # ""
533
582
  ----
534
583
 
535
584
  ==== Pathname
@@ -543,7 +592,7 @@ construct a valid path.
543
592
 
544
593
  [source,ruby]
545
594
  ----
546
- Pathname(nil) # => Pathname("")
595
+ Pathname(nil) # Pathname("")
547
596
  ----
548
597
 
549
598
  ===== .home
@@ -552,7 +601,7 @@ Answers user home directory.
552
601
 
553
602
  [source,ruby]
554
603
  ----
555
- Pathname.home # => Pathname "/Users/bkuhlmann"
604
+ Pathname.home # Pathname "/Users/demo"
556
605
  ----
557
606
 
558
607
  ===== .make_temp_dir
@@ -569,13 +618,13 @@ reality, these paths will be longer depending on which operating system you are
569
618
 
570
619
  [source,ruby]
571
620
  ----
572
- Pathname.make_temp_dir # => Pathname:/var/folders/T/temp-20200101-16940-r8
573
- Pathname.make_temp_dir prefix: "prefix-" # => Pathname:/var/folders/T/prefix-20200101-16940-r8
574
- Pathname.make_temp_dir suffix: "-suffix" # => Pathname:/var/folders/T/temp-20200101-16940-r8-suffix
575
- Pathname.make_temp_dir prefix: "prefix-", suffix: "-suffix" # => Pathname:/var/folders/T/prefix-20200101-16940-r8-suffix
576
- Pathname.make_temp_dir root: "/example" # => Pathname:/example/temp-20200101-16940-r8
577
- Pathname.make_temp_dir { "I am a block result" } # => "I am a block result"
578
- Pathname.make_temp_dir { |path| path.join "sub_dir" } # => Pathname:/var/folders/T/temp-20200101-16940-r8/sub_dir
621
+ Pathname.make_temp_dir # Pathname:/var/folders/T/temp-20200101-16940-r8
622
+ Pathname.make_temp_dir prefix: "prefix-" # Pathname:/var/folders/T/prefix-20200101-16940-r8
623
+ Pathname.make_temp_dir suffix: "-suffix" # Pathname:/var/folders/T/temp-20200101-16940-r8-suffix
624
+ Pathname.make_temp_dir prefix: "prefix-", suffix: "-suffix" # Pathname:/var/folders/T/prefix-20200101-16940-r8-suffix
625
+ Pathname.make_temp_dir root: "/example" # Pathname:/example/temp-20200101-16940-r8
626
+ Pathname.make_temp_dir { "I am a block result" } # "I am a block result"
627
+ Pathname.make_temp_dir { |path| path.join "sub_dir" } # Pathname:/var/folders/T/temp-20200101-16940-r8/sub_dir
579
628
  ----
580
629
 
581
630
  ===== .require_tree
@@ -612,7 +661,7 @@ Answers operating system root path.
612
661
 
613
662
  [source,ruby]
614
663
  ----
615
- Pathname.root # => Pathname "/"
664
+ Pathname.root # Pathname "/"
616
665
  ----
617
666
 
618
667
  ===== #change_dir
@@ -622,13 +671,13 @@ link:https://rubyapi.org/o/Dir.chdir#method-c-chdir[Dir.chdir] for details.
622
671
 
623
672
  [source,ruby]
624
673
  ----
625
- Pathname.pwd # => "/"
626
- Pathname("/test").make_dir.change_dir # => Pathname "/test"
627
- Pathname.pwd # => "/test"
628
-
629
- Pathname.pwd # => "/"
630
- Pathname("/test").make_dir.change_dir { "example" } # => "example"
631
- Pathname.pwd # => "/"
674
+ current = Pathname.pwd # "$HOME/demo" (Present Working Directory)
675
+ custom = current.join("test").make_dir # Pathname "$HOME/demo/test"
676
+ custom.change_dir # "$HOME/demo/test" (Present Working Directory)
677
+ current.change_dir # "$HOME/demo" (Present Working Directory)
678
+ custom.change_dir { "example" } # "example"
679
+ custom.change_dir { |path| path } # Pathname "$HOME/demo/test"
680
+ Pathname.pwd # "$HOME/demo" (Present Working Directory)
632
681
  ----
633
682
 
634
683
  ===== #copy
@@ -637,7 +686,31 @@ Copies file from current location to new location while answering itself so it c
637
686
 
638
687
  [source,ruby]
639
688
  ----
640
- Pathname("input.txt").copy Pathname("output.txt") # => Pathname("input.txt")
689
+ Pathname("input.txt").copy Pathname("output.txt") # Pathname("input.txt")
690
+ ----
691
+
692
+ ===== #deep_touch
693
+
694
+ Has all of the same functionality as the `#touch` method while being able to create ancestor
695
+ directories no matter how deeply nested the file might be.
696
+
697
+ [source,ruby]
698
+ ----
699
+ Pathname("a/b/c/d.txt").touch # Pathname("a/b/c/d.txt")
700
+ Pathname("a/b/c/d.txt").touch Time.now - 1 # Pathname("a/b/c/d.txt")
701
+ ----
702
+
703
+ ===== #delete
704
+
705
+ Deletes file or directory and answers itself so it can be chained.
706
+
707
+ [source,ruby]
708
+ ----
709
+ # When path exists.
710
+ Pathname("/example.txt").touch.delete # Pathname("/example")
711
+
712
+ # When path doesn't exist.
713
+ Pathname("/example.txt").delete # Errno::ENOENT
641
714
  ----
642
715
 
643
716
  ===== #directories
@@ -646,9 +719,23 @@ Answers all directories or filtered directories for current path.
646
719
 
647
720
  [source,ruby]
648
721
  ----
649
- Pathname("/example").directories # => [Pathname("a"), Pathname("b")]
650
- Pathname("/example").directories "a*" # => [Pathname("a")]
651
- Pathname("/example").directories flag: File::FNM_DOTMATCH # => [Pathname(".."), Pathname(".")]
722
+ Pathname("/example").directories # [Pathname("a"), Pathname("b")]
723
+ Pathname("/example").directories "a*" # [Pathname("a")]
724
+ Pathname("/example").directories flag: File::FNM_DOTMATCH # [Pathname(".."), Pathname(".")]
725
+ ----
726
+
727
+ ===== #empty
728
+
729
+ Empties a directory of children (i.e. folders, nested folders, or files) or clears an existing file
730
+ of contents. If a directory or file doesn't exist, it will be created.
731
+
732
+ [source,ruby]
733
+ ----
734
+ directory = Pathname("test").make_path
735
+ file = directory.join("test.txt").write("example")
736
+
737
+ file.empty.read # ""
738
+ directory.empty.children # []
652
739
  ----
653
740
 
654
741
  ===== #extensions
@@ -657,7 +744,7 @@ Answers file extensions as an array.
657
744
 
658
745
  [source,ruby]
659
746
  ----
660
- Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
747
+ Pathname("example.txt.erb").extensions # [".txt", ".erb"]
661
748
  ----
662
749
 
663
750
  ===== #files
@@ -666,9 +753,9 @@ Answers all files or filtered files for current path.
666
753
 
667
754
  [source,ruby]
668
755
  ----
669
- Pathname("/example").files # => [Pathname("a.txt"), Pathname("a.png")]
670
- Pathname("/example").files "*.png" # => [Pathname("a.png")]
671
- Pathname("/example").files flag: File::FNM_DOTMATCH # => [Pathname(".ruby-version")]
756
+ Pathname("/example").files # [Pathname("a.txt"), Pathname("a.png")]
757
+ Pathname("/example").files "*.png" # [Pathname("a.png")]
758
+ Pathname("/example").files flag: File::FNM_DOTMATCH # [Pathname(".ruby-version")]
672
759
  ----
673
760
 
674
761
  ===== #gsub
@@ -678,10 +765,10 @@ Same behavior as `String#gsub` but answers a path with patterns replaced with de
678
765
  [source,ruby]
679
766
  ----
680
767
  Pathname("/a/path/some/path").gsub("path", "test")
681
- # => Pathname("/a/test/some/test")
768
+ # Pathname("/a/test/some/test")
682
769
 
683
770
  Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test")
684
- # => Pathname("/test/some/test")
771
+ # Pathname("/test/some/test")
685
772
  ----
686
773
 
687
774
  ===== #make_ancestors
@@ -690,9 +777,9 @@ Ensures all ancestor directories are created for a path.
690
777
 
691
778
  [source,ruby]
692
779
  ----
693
- Pathname("/one/two").make_ancestors # => Pathname("/one/two")
694
- Pathname("/one").exist? # => true
695
- Pathname("/one/two").exist? # => false
780
+ Pathname("/one/two").make_ancestors # Pathname("/one/two")
781
+ Pathname("/one").exist? # true
782
+ Pathname("/one/two").exist? # false
696
783
  ----
697
784
 
698
785
  ===== #make_dir
@@ -702,8 +789,8 @@ not throwing errors when directory does exist in order to ensure the pathname ca
702
789
 
703
790
  [source,ruby]
704
791
  ----
705
- Pathname("/one").make_dir # => Pathname("/one")
706
- Pathname("/one").make_dir.make_dir # => Pathname("/one")
792
+ Pathname("/one").make_dir # Pathname("/one")
793
+ Pathname("/one").make_dir.make_dir # Pathname("/one")
707
794
  ----
708
795
 
709
796
  ===== #make_path
@@ -713,8 +800,8 @@ not throwing errors when directory does exist in order to ensure the pathname ca
713
800
 
714
801
  [source,ruby]
715
802
  ----
716
- Pathname("/one/two/three").make_path # => Pathname("/one/two/three")
717
- Pathname("/one/two/three").make_path.make_path # => Pathname("/one/two/three")
803
+ Pathname("/one/two/three").make_path # Pathname("/one/two/three")
804
+ Pathname("/one/two/three").make_path.make_path # Pathname("/one/two/three")
718
805
  ----
719
806
 
720
807
  ===== #name
@@ -723,7 +810,7 @@ Answers file name without extension.
723
810
 
724
811
  [source,ruby]
725
812
  ----
726
- Pathname("example.txt").name # => Pathname("example")
813
+ Pathname("example.txt").name # Pathname("example")
727
814
  ----
728
815
 
729
816
  ===== #relative_parent
@@ -732,7 +819,7 @@ Answers relative path from parent directory. This is a complement to `#relative_
732
819
 
733
820
  [source,ruby]
734
821
  ----
735
- Pathname("/one/two/three").relative_parent("/one") # => Pathname "two"
822
+ Pathname("/one/two/three").relative_parent("/one") # Pathname "two"
736
823
  ----
737
824
 
738
825
  ===== #remove_dir
@@ -742,9 +829,9 @@ not throwing errors when directory does exist in order to ensure the pathname ca
742
829
 
743
830
  [source,ruby]
744
831
  ----
745
- Pathname("/test").make_dir.remove_dir.exist? # => false
746
- Pathname("/test").remove_dir # => Pathname("/test")
747
- Pathname("/test").remove_dir.remove_dir # => Pathname("/test")
832
+ Pathname("/test").make_dir.remove_dir.exist? # false
833
+ Pathname("/test").remove_dir # Pathname("/test")
834
+ Pathname("/test").remove_dir.remove_dir # Pathname("/test")
748
835
  ----
749
836
 
750
837
  ===== #remove_tree
@@ -758,14 +845,14 @@ parent_path = Pathname "/one"
758
845
  child_path = parent_path.join "two"
759
846
 
760
847
  child_path.make_path
761
- child_path.remove_tree # => Pathname "/one/two"
762
- child_path.exist? # => false
763
- paremt_path.exist? # => true
848
+ child_path.remove_tree # Pathname "/one/two"
849
+ child_path.exist? # false
850
+ paremt_path.exist? # true
764
851
 
765
852
  child_path.make_path
766
- parent_path.remove_tree # => Pathname "/one"
767
- child_path.exist? # => false
768
- parent_path.exist? # => false
853
+ parent_path.remove_tree # Pathname "/one"
854
+ child_path.exist? # false
855
+ parent_path.exist? # false
769
856
  ----
770
857
 
771
858
  ===== #rewrite
@@ -775,18 +862,21 @@ immediate writing back to the same file.
775
862
 
776
863
  [source,ruby]
777
864
  ----
778
- Pathname("/test.txt").rewrite # => Pathname("/test.txt")
779
- Pathname("/test.txt").rewrite { |body| body.sub "[token]", "example" } # => Pathname("/test.txt")
865
+ Pathname("/test.txt").rewrite # Pathname("/test.txt")
866
+ Pathname("/test.txt").rewrite { |body| body.sub "[token]", "example" } # Pathname("/test.txt")
780
867
  ----
781
868
 
782
869
  ===== #touch
783
870
 
784
- Updates access and modification times for path. Defaults to current time.
871
+ Updates access and modification times for an existing path by defaulting to current time. When path
872
+ doesn't exist, it will be created as a file.
785
873
 
786
874
  [source,ruby]
787
875
  ----
788
- Pathname("example.txt").touch # => Pathname("example.txt")
789
- Pathname("example.txt").touch Time.now - 1 # => Pathname("example.txt")
876
+ Pathname("example").touch # Pathname("example")
877
+ Pathname("example").touch Time.now - 1 # Pathname("example")
878
+ Pathname("example.txt").touch # Pathname("example.txt")
879
+ Pathname("example.txt").touch Time.now - 1 # Pathname("example.txt")
790
880
  ----
791
881
 
792
882
  ===== #write
@@ -796,9 +886,9 @@ options.
796
886
 
797
887
  [source,ruby]
798
888
  ----
799
- Pathname("example.txt").write "test" # => Pathname("example.txt")
800
- Pathname("example.txt").write "test", offset: 1 # => Pathname("example.txt")
801
- Pathname("example.txt").write "test", mode: "a" # => Pathname("example.txt")
889
+ Pathname("example.txt").write "test" # Pathname("example.txt")
890
+ Pathname("example.txt").write "test", offset: 1 # Pathname("example.txt")
891
+ Pathname("example.txt").write "test", mode: "a" # Pathname("example.txt")
802
892
  ----
803
893
 
804
894
  ==== String
@@ -809,7 +899,7 @@ Answers `true`/`false` based on whether string is blank, `<space>`, `\n`, `\t`,
809
899
 
810
900
  [source,ruby]
811
901
  ----
812
- " \n\t\r".blank? # => true
902
+ " \n\t\r".blank? # true
813
903
  ----
814
904
 
815
905
  ===== #camelcase
@@ -818,7 +908,7 @@ Answers a camelcased string.
818
908
 
819
909
  [source,ruby]
820
910
  ----
821
- "this_is_an_example".camelcase # => "ThisIsAnExample"
911
+ "this_is_an_example".camelcase # "ThisIsAnExample"
822
912
  ----
823
913
 
824
914
  ===== #down
@@ -827,7 +917,7 @@ Answers string with only first letter downcased.
827
917
 
828
918
  [source,ruby]
829
919
  ----
830
- "EXAMPLE".down # => "eXAMPLE"
920
+ "EXAMPLE".down # "eXAMPLE"
831
921
  ----
832
922
 
833
923
  ===== #first
@@ -836,8 +926,8 @@ Answers first character of a string or first set of characters if given a number
836
926
 
837
927
  [source,ruby]
838
928
  ----
839
- "example".first # => "e"
840
- "example".first 4 # => "exam"
929
+ "example".first # "e"
930
+ "example".first 4 # "exam"
841
931
  ----
842
932
 
843
933
  ===== #indent
@@ -846,11 +936,11 @@ Answers string indented by two spaces by default.
846
936
 
847
937
  [source,ruby]
848
938
  ----
849
- "example".indent # => " example"
850
- "example".indent 0 # => "example"
851
- "example".indent -1 # => "example"
852
- "example".indent 2 # => " example"
853
- "example".indent 3, padding: " " # => " example"
939
+ "example".indent # " example"
940
+ "example".indent 0 # "example"
941
+ "example".indent -1 # "example"
942
+ "example".indent 2 # " example"
943
+ "example".indent 3, padding: " " # " example"
854
944
  ----
855
945
 
856
946
  ===== #last
@@ -859,8 +949,48 @@ Answers last character of a string or last set of characters if given a number.
859
949
 
860
950
  [source,ruby]
861
951
  ----
862
- "instant".last # => "t"
863
- "instant".last 3 # => "ant"
952
+ "instant".last # "t"
953
+ "instant".last 3 # "ant"
954
+ ----
955
+
956
+ ===== #pluralize
957
+
958
+ Answers plural form of self when given a suffix to add. The plural form of the word can be
959
+ dynamically calculated when given a count and a replacement pattern (i.e. string or regular
960
+ expression) can be supplied for further specificity. Usage is based on
961
+ link:https://en.wikipedia.org/wiki/English_plurals[plurals in English] which may or may not work
962
+ well in other languages.
963
+
964
+ [source,ruby]
965
+ ----
966
+ "apple".pluralize "s" # apples
967
+ "apple".pluralize "s", count: 0 # apples
968
+ "apple".pluralize "s", count: 1 # apple
969
+ "apple".pluralize "s", count: -1 # apple
970
+ "apple".pluralize "s", count: 2 # apples
971
+ "apple".pluralize "s", count: -2 # apples
972
+ "cactus".pluralize "i", replace: "us" # cacti
973
+ "cul-de-sac".pluralize "ls", replace: "l" # culs-de-sac
974
+ ----
975
+
976
+ ===== #singularize
977
+
978
+ Answers singular form of self when given a suffix to remove (can be a string or a regular
979
+ expression). The singular form of the word can be dynamically calculated when given a count and a
980
+ replacement string can be supplied for further specificity. Usage is based on
981
+ link:https://en.wikipedia.org/wiki/English_plurals[plurals in English] which may or may not work
982
+ well in other languages.
983
+
984
+ [source,ruby]
985
+ ----
986
+ "apples".singularize "s" # apple
987
+ "apples".singularize "s", count: 0 # apples
988
+ "apples".singularize "s", count: 1 # apple
989
+ "apples".singularize "s", count: -1 # apple
990
+ "apples".singularize "s", count: 2 # apples
991
+ "apples".singularize "s", count: -2 # apples
992
+ "cacti".singularize "i", replace: "us" # cactus
993
+ "culs-de-sac".singularize "ls", replace: "l" # cul-de-sac
864
994
  ----
865
995
 
866
996
  ===== #snakecase
@@ -869,7 +999,7 @@ Answers a snakecased string.
869
999
 
870
1000
  [source,ruby]
871
1001
  ----
872
- "ThisIsAnExample".snakecase # => "this_is_an_example"
1002
+ "ThisIsAnExample".snakecase # "this_is_an_example"
873
1003
  ----
874
1004
 
875
1005
  ===== #titleize
@@ -878,7 +1008,7 @@ Answers titleized string.
878
1008
 
879
1009
  [source,ruby]
880
1010
  ----
881
- "ThisIsAnExample".titleize # => "This Is An Example"
1011
+ "ThisIsAnExample".titleize # "This Is An Example"
882
1012
  ----
883
1013
 
884
1014
  ===== #to_bool
@@ -887,11 +1017,11 @@ Answers string as a boolean.
887
1017
 
888
1018
  [source,ruby]
889
1019
  ----
890
- "true".to_bool # => true
891
- "yes".to_bool # => true
892
- "1".to_bool # => true
893
- "".to_bool # => false
894
- "example".to_bool # => false
1020
+ "true".to_bool # true
1021
+ "yes".to_bool # true
1022
+ "1".to_bool # true
1023
+ "".to_bool # false
1024
+ "example".to_bool # false
895
1025
  ----
896
1026
 
897
1027
  ===== #up
@@ -900,7 +1030,7 @@ Answers string with only first letter upcased.
900
1030
 
901
1031
  [source,ruby]
902
1032
  ----
903
- "example".up # => "Example"
1033
+ "example".up # "Example"
904
1034
  ----
905
1035
 
906
1036
  ==== String IO
@@ -914,12 +1044,12 @@ Answers full string by rewinding to beginning of string and reading all content.
914
1044
  io = StringIO.new
915
1045
  io.write "This is a test."
916
1046
 
917
- io.reread # => "This is a test."
918
- io.reread 4 # => "This"
1047
+ io.reread # "This is a test."
1048
+ io.reread 4 # "This"
919
1049
 
920
1050
  buffer = "".dup
921
- io.reread(buffer: buffer) # => "This is a test."
922
- buffer # => "This is a test."
1051
+ io.reread(buffer: buffer) # "This is a test."
1052
+ buffer # "This is a test."
923
1053
  ----
924
1054
 
925
1055
  ==== Struct
@@ -930,8 +1060,8 @@ Answers whether a struct was constructed with keyword or positional arguments.
930
1060
 
931
1061
  [source,ruby]
932
1062
  ----
933
- Struct.new(:a, keyword_init: true).keyworded? # => true
934
- Struct.new(:a).keyworded? # => false
1063
+ Struct.new(:a, keyword_init: true).keyworded? # true
1064
+ Struct.new(:a).keyworded? # false
935
1065
  ----
936
1066
 
937
1067
  ===== .with_keywords
@@ -942,14 +1072,14 @@ whether the struct was constructed with positional or keyword arguments.
942
1072
  [source,ruby]
943
1073
  ----
944
1074
  Example = Struct.new :a, :b, :c
945
- Example.with_keywords a: 1, b: 2, c: 3 # => #<struct a=1, b=2, c=3>
946
- Example.with_keywords a: 1 # => #<struct a=1, b=nil, c=nil>
947
- Example.with_keywords c: 1 # => #<struct a=nil, b=nil, c=1>
1075
+ Example.with_keywords a: 1, b: 2, c: 3 # "#<struct a=1, b=2, c=3>"
1076
+ Example.with_keywords a: 1 # "#<struct a=1, b=nil, c=nil>"
1077
+ Example.with_keywords c: 1 # "#<struct a=nil, b=nil, c=1>"
948
1078
 
949
1079
  Example = Struct.new :a, :b, :c, keyword_init: true
950
- Example.with_keywords a: 1, b: 2, c: 3 # => #<struct a=1, b=2, c=3>
951
- Example.with_keywords a: 1 # => #<struct a=1, b=nil, c=nil>
952
- Example.with_keywords c: 1 # => #<struct a=nil, b=nil, c=1>
1080
+ Example.with_keywords a: 1, b: 2, c: 3 # "#<struct a=1, b=2, c=3>"
1081
+ Example.with_keywords a: 1 # "#<struct a=1, b=nil, c=nil>"
1082
+ Example.with_keywords c: 1 # "#<struct a=nil, b=nil, c=1>"
953
1083
  ----
954
1084
 
955
1085
  ===== .with_positions
@@ -960,12 +1090,12 @@ whether the struct was constructed with positional or keyword arguments.
960
1090
  [source,ruby]
961
1091
  ----
962
1092
  Example = Struct.new :a, :b, :c
963
- Example.with_positions 1, 2, 3 # => #<struct a=1, b=2, c=3>
964
- Example.with_positions 1 # => #<struct a=1, b=nil, c=nil>
1093
+ Example.with_positions 1, 2, 3 # "#<struct a=1, b=2, c=3>"
1094
+ Example.with_positions 1 # "#<struct a=1, b=nil, c=nil>"
965
1095
 
966
1096
  Example = Struct.new :a, :b, :c, keyword_init: true
967
- Example.with_positions 1, 2, 3 # => #<struct a=1, b=2, c=3>
968
- Example.with_positions 1 # => #<struct a=1, b=nil, c=nil>
1097
+ Example.with_positions 1, 2, 3 # "#<struct a=1, b=2, c=3>"
1098
+ Example.with_positions 1 # "#<struct a=1, b=nil, c=nil>"
969
1099
  ----
970
1100
 
971
1101
  ===== #merge
@@ -976,17 +1106,17 @@ Merges multiple attributes without mutating itself.
976
1106
  ----
977
1107
  Example = Struct.new :a, :b, :c
978
1108
  example = Example[1, 2, 3]
979
- example.merge a: 10 # => #<struct a=10, b=2, c=3>
980
- example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
981
- example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
982
- example # => #<struct a=1, b=2, c=3>
1109
+ example.merge a: 10 # "#<struct a=10, b=2, c=3>"
1110
+ example.merge a: 10, c: 30 # "#<struct a=10, b=2, c=30>"
1111
+ example.merge a: 10, b: 20, c: 30 # "#<struct a=10, b=20, c=30>"
1112
+ example # "#<struct a=1, b=2, c=3>"
983
1113
 
984
1114
  Example = Struct.new :a, :b, :c, keyword_init: true
985
1115
  example = Example[a: 1, b: 2, c: 3]
986
- example.merge a: 10 # => #<struct a=10, b=2, c=3>
987
- example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
988
- example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
989
- example # => #<struct a=1, b=2, c=3>
1116
+ example.merge a: 10 # "#<struct a=10, b=2, c=3>"
1117
+ example.merge a: 10, c: 30 # "#<struct a=10, b=2, c=30>"
1118
+ example.merge a: 10, b: 20, c: 30 # "#<struct a=10, b=20, c=30>"
1119
+ example # "#<struct a=1, b=2, c=3>"
990
1120
  ----
991
1121
 
992
1122
  ===== #merge!
@@ -997,17 +1127,17 @@ Merges multiple attributes while mutating itself.
997
1127
  ----
998
1128
  Example = Struct.new :a, :b, :c
999
1129
  example = Example[1, 2, 3]
1000
- example.merge! a: 10 # => #<struct a=10, b=2, c=3>
1001
- example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
1002
- example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
1003
- example # => #<struct a=10, b=20, c=30>
1130
+ example.merge! a: 10 # "#<struct a=10, b=2, c=3>"
1131
+ example.merge! a: 10, c: 30 # "#<struct a=10, b=2, c=30>"
1132
+ example.merge! a: 10, b: 20, c: 30 # "#<struct a=10, b=20, c=30>"
1133
+ example # "#<struct a=10, b=20, c=30>"
1004
1134
 
1005
1135
  Example = Struct.new :a, :b, :c, keyword_init: true
1006
1136
  example = Example[a: 1, b: 2, c: 3]
1007
- example.merge! a: 10 # => #<struct a=10, b=2, c=3>
1008
- example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
1009
- example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
1010
- example # => #<struct a=10, b=20, c=30>
1137
+ example.merge! a: 10 # "#<struct a=10, b=2, c=3>"
1138
+ example.merge! a: 10, c: 30 # "#<struct a=10, b=2, c=30>"
1139
+ example.merge! a: 10, b: 20, c: 30 # "#<struct a=10, b=20, c=30>"
1140
+ example # "#<struct a=10, b=20, c=30>"
1011
1141
  ----
1012
1142
 
1013
1143
  ===== #revalue
@@ -1023,11 +1153,11 @@ below but a keyword struct would work too.
1023
1153
  Example = Struct.new :a, :b, :c
1024
1154
 
1025
1155
  example = Example[1, 2, 3]
1026
- example.revalue { |value| value * 2 } # => #<struct a=2, b=4, c=6>
1027
- example.revalue(c: 2) { |previous, current| previous + current } # => #<struct a=1, b=2, c=5>
1028
- example.revalue c: 2 # => #<struct a=1, b=2, c=3>
1029
- example.revalue # => #<struct a=1, b=2, c=3>
1030
- example # => #<struct a=1, b=2, c=3>
1156
+ example.revalue { |value| value * 2 } # "#<struct a=2, b=4, c=6>"
1157
+ example.revalue(c: 2) { |previous, current| previous + current } # "#<struct a=1, b=2, c=5>"
1158
+ example.revalue c: 2 # "#<struct a=1, b=2, c=3>"
1159
+ example.revalue # "#<struct a=1, b=2, c=3>"
1160
+ example # "#<struct a=1, b=2, c=3>"
1031
1161
 
1032
1162
  ----
1033
1163
 
@@ -1044,18 +1174,36 @@ keyword struct would work too.
1044
1174
  Example = Struct.new :a, :b, :c
1045
1175
 
1046
1176
  example = Example[1, 2, 3]
1047
- example.revalue! { |value| value * 2 } # => #<struct a=2, b=4, c=6>
1048
- example # => #<struct a=2, b=4, c=6>
1177
+ example.revalue! { |value| value * 2 } # "#<struct a=2, b=4, c=6>"
1178
+ example # "#<struct a=2, b=4, c=6>"
1049
1179
 
1050
1180
  example = Example[1, 2, 3]
1051
- example.revalue!(c: 2) { |previous, current| previous + current } # => #<struct a=1, b=2, c=5>
1052
- example # => #<struct a=1, b=2, c=5>
1181
+ example.revalue!(c: 2) { |previous, current| previous + current } # "#<struct a=1, b=2, c=5>"
1182
+ example # "#<struct a=1, b=2, c=5>"
1053
1183
 
1054
1184
  example = Example[1, 2, 3]
1055
- example.revalue! c: 2 # => #<struct a=1, b=2, c=3>
1056
- example.revalue! # => #<struct a=1, b=2, c=3>
1057
- example # => #<struct a=1, b=2, c=3>
1185
+ example.revalue! c: 2 # "#<struct a=1, b=2, c=3>"
1186
+ example.revalue! # "#<struct a=1, b=2, c=3>"
1187
+ example # "#<struct a=1, b=2, c=3>"
1188
+ ----
1189
+
1190
+ ==== Symbol
1191
+
1192
+ ===== #call
1193
+
1194
+ Enhances symbol-to-proc by allowing you to send additional arguments and/or a block. This only works
1195
+ with public methods in order to not break encapsulation.
1196
+
1197
+ [source,ruby]
1058
1198
  ----
1199
+ %w[clue crow cow].map(&:tr.call("c", "b")) # ["blue", "brow", "bow"]
1200
+ [%w[a b c], %w[c a b]].map(&:index.call { |element| element == "b" }) # [1, 2]
1201
+ %w[1.outside 2.inside].map(&:sub.call(/\./) { |bullet| bullet + " " }) # ["1. outside", "2. inside"]
1202
+ [1, 2, 3].map(&:to_s.call) # ["1", "2", "3"]
1203
+ ----
1204
+
1205
+ ⚠️ Use of `#call` without any arguments or block should be avoided in order to not incur extra
1206
+ processing costs since the original symbol-to-proc call can used instead.
1059
1207
 
1060
1208
  == Development
1061
1209
 
@@ -1101,6 +1249,11 @@ participating in this project you agree to abide by its terms.
1101
1249
 
1102
1250
  Read link:CONTRIBUTING.adoc[CONTRIBUTING] for details.
1103
1251
 
1252
+ == Community
1253
+
1254
+ Feel free to link:https://www.alchemists.io/community[join the commmunity] for discussions related
1255
+ to this project and much more.
1256
+
1104
1257
  == License
1105
1258
 
1106
1259
  Read link:LICENSE.adoc[LICENSE] for details.