refinements 7.10.0 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/LICENSE.adoc +1 -1
- data/README.adoc +374 -159
- data/lib/refinements.rb +2 -0
- data/lib/refinements/arrays.rb +20 -2
- data/lib/refinements/hashes.rb +45 -45
- data/lib/refinements/identity.rb +1 -1
- data/lib/refinements/ios.rb +35 -0
- data/lib/refinements/pathnames.rb +35 -5
- data/lib/refinements/strings.rb +29 -29
- data/lib/refinements/structs.rb +16 -0
- metadata +32 -16
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 756d9dcbbc60385370835ad8001dd4fb84f6848aba8ca51cbe949fcd2aaa72a4
|
|
4
|
+
data.tar.gz: f09562bfe5991533c166f5aa0aa215a3f2fe8df3604e85dd3404a7688df67980
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b37235bf15f3b959dd295a22c3e9c89dff28faa4124da955b0e27b2bef7db505d3093dc56369550d2863e6dc2ca3d10bbfe248da1e7a70f0eaee7fb351bd4e9f
|
|
7
|
+
data.tar.gz: 0c7aeed58557e626cc6494d761e79c4a0bcb60f42e79d83cef01676c9fd5fbf838dd97f4b89c3234a978455d3acfb6bdd3f715ed55dfed05a92e5f0e86d7426d
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/LICENSE.adoc
CHANGED
|
@@ -150,7 +150,7 @@ additional liability.
|
|
|
150
150
|
|
|
151
151
|
END OF TERMS AND CONDITIONS
|
|
152
152
|
|
|
153
|
-
Copyright link:https://www.alchemists.io[
|
|
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]
|
data/README.adoc
CHANGED
|
@@ -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
|
-
|
|
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
|
-
===== #
|
|
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].
|
|
150
|
-
[1, 2, 3].
|
|
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
|
-
===== #
|
|
151
|
+
===== #intersperse
|
|
154
152
|
|
|
155
|
-
|
|
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
|
-
[
|
|
160
|
-
[
|
|
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
|
-
===== #
|
|
367
|
+
===== #recurse
|
|
291
368
|
|
|
292
|
-
|
|
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
|
|
297
|
-
example.
|
|
298
|
-
example
|
|
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
|
-
===== #
|
|
379
|
+
===== #rekey
|
|
302
380
|
|
|
303
|
-
|
|
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.
|
|
309
|
-
example
|
|
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
|
-
===== #
|
|
390
|
+
===== #rekey!
|
|
313
391
|
|
|
314
|
-
|
|
392
|
+
Transforms keys per mapping (size of mapping can vary) while mutating itself.
|
|
315
393
|
|
|
316
394
|
[source,ruby]
|
|
317
395
|
----
|
|
318
|
-
example = {
|
|
319
|
-
example.
|
|
320
|
-
example
|
|
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
|
-
===== #
|
|
401
|
+
===== #reverse_merge
|
|
324
402
|
|
|
325
|
-
|
|
403
|
+
Merges calling hash into passed in hash without mutating itself.
|
|
326
404
|
|
|
327
405
|
[source,ruby]
|
|
328
406
|
----
|
|
329
|
-
example = {
|
|
330
|
-
example.
|
|
331
|
-
example
|
|
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
|
-
===== #
|
|
412
|
+
===== #reverse_merge!
|
|
335
413
|
|
|
336
|
-
Merges
|
|
414
|
+
Merges calling hash into passed in hash while mutating itself.
|
|
337
415
|
|
|
338
416
|
[source,ruby]
|
|
339
417
|
----
|
|
340
|
-
example = {a:
|
|
341
|
-
example.
|
|
342
|
-
example
|
|
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
|
-
===== #
|
|
423
|
+
===== #stringify_keys
|
|
346
424
|
|
|
347
|
-
|
|
425
|
+
Converts keys to strings without mutating itself.
|
|
348
426
|
|
|
349
427
|
[source,ruby]
|
|
350
428
|
----
|
|
351
|
-
example = {a:
|
|
352
|
-
example.
|
|
353
|
-
example
|
|
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
|
-
===== #
|
|
434
|
+
===== #stringify_keys!
|
|
357
435
|
|
|
358
|
-
|
|
436
|
+
Converts keys to strings while mutating itself.
|
|
359
437
|
|
|
360
438
|
[source,ruby]
|
|
361
439
|
----
|
|
362
|
-
example = {a:
|
|
363
|
-
example.
|
|
364
|
-
example
|
|
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
|
-
===== #
|
|
445
|
+
===== #symbolize_keys
|
|
368
446
|
|
|
369
|
-
|
|
447
|
+
Converts keys to symbols without mutating itself.
|
|
370
448
|
|
|
371
449
|
[source,ruby]
|
|
372
450
|
----
|
|
373
|
-
example = {a
|
|
374
|
-
example.
|
|
375
|
-
example
|
|
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
|
-
===== #
|
|
456
|
+
===== #symbolize_keys!
|
|
379
457
|
|
|
380
|
-
|
|
458
|
+
Converts keys to symbols while mutating itself.
|
|
381
459
|
|
|
382
460
|
[source,ruby]
|
|
383
461
|
----
|
|
384
|
-
example = {"a" =>
|
|
385
|
-
example.
|
|
386
|
-
example
|
|
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
|
-
===== #
|
|
467
|
+
===== #use
|
|
390
468
|
|
|
391
|
-
|
|
469
|
+
Passes each hash value as a block argument for further processing.
|
|
392
470
|
|
|
393
471
|
[source,ruby]
|
|
394
472
|
----
|
|
395
|
-
example = {"
|
|
396
|
-
example.
|
|
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
|
-
|
|
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
|
-
=====
|
|
479
|
+
===== .void
|
|
413
480
|
|
|
414
|
-
|
|
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
|
-
|
|
419
|
-
|
|
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
|
-
===== #
|
|
491
|
+
===== #redirect
|
|
424
492
|
|
|
425
|
-
|
|
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
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
-
===== #
|
|
505
|
+
===== #reread
|
|
435
506
|
|
|
436
|
-
|
|
507
|
+
Answers full stream by rewinding to beginning of stream and reading all content.
|
|
437
508
|
|
|
438
509
|
[source,ruby]
|
|
439
510
|
----
|
|
440
|
-
|
|
441
|
-
|
|
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
|
-
|
|
514
|
+
io.reread # => "This is a test."
|
|
515
|
+
io.reread 4 # => "This"
|
|
448
516
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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
|
-
===== #
|
|
522
|
+
===== #squelch
|
|
457
523
|
|
|
458
|
-
|
|
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
|
-
|
|
463
|
-
|
|
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
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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
|
-
===== #
|
|
549
|
+
===== #change_dir
|
|
481
550
|
|
|
482
|
-
|
|
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
|
|
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
|
-
===== #
|
|
669
|
+
===== #remove_dir
|
|
552
670
|
|
|
553
|
-
|
|
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("/
|
|
558
|
-
Pathname("/
|
|
559
|
-
Pathname("/
|
|
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
|
-
===== #
|
|
681
|
+
===== #remove_tree
|
|
563
682
|
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
|
|
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
|
-
===== #
|
|
702
|
+
===== #rewrite
|
|
573
703
|
|
|
574
|
-
|
|
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("
|
|
579
|
-
Pathname("
|
|
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
|
-
|
|
583
|
-
|
|
584
|
-
===== #first
|
|
713
|
+
===== #touch
|
|
585
714
|
|
|
586
|
-
|
|
715
|
+
Updates access and modification times for path. Defaults to current time.
|
|
587
716
|
|
|
588
717
|
[source,ruby]
|
|
589
718
|
----
|
|
590
|
-
"example".
|
|
591
|
-
"example".
|
|
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
|
-
===== #
|
|
723
|
+
===== #write
|
|
595
724
|
|
|
596
|
-
|
|
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
|
-
"
|
|
601
|
-
"
|
|
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
|
-
===== #
|
|
746
|
+
===== #camelcase
|
|
614
747
|
|
|
615
|
-
Answers
|
|
748
|
+
Answers a camelcased string.
|
|
616
749
|
|
|
617
750
|
[source,ruby]
|
|
618
751
|
----
|
|
619
|
-
"
|
|
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
|
-
===== #
|
|
787
|
+
===== #last
|
|
645
788
|
|
|
646
|
-
Answers a
|
|
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
|
-
"
|
|
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
|
|
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
|