refinements 13.3.0 → 13.5.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/README.adoc +102 -58
- data/lib/refinements/hash.rb +14 -0
- data/lib/refinements/pathname.rb +11 -2
- data/lib/refinements/string.rb +10 -3
- data/lib/refinements/struct.rb +17 -5
- data/refinements.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- 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: c4f7a616f560224da3b786d73ad6f8f206c0aacba2b0701bbe91c5b8ecfec2c2
|
4
|
+
data.tar.gz: 9f166af1d48f1e00f0b8e3024f19fcfbd1cbbb8b8180bd798a69086455bc2079
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9044d5b55f7349284ae45ff1a98d3c34bb2d4e1511df391094bbef41b8cb8da1f4aae96703bf617c19483269881f1d9f04ba9ba42009868ef7abc5d7953332ac
|
7
|
+
data.tar.gz: fd593a7bb6cb5239618b5eedd077f50df25bcad1be4ec7ed2bc6ec7d8a87c3d2f6ada9c145a55fa802c3afa8ac2b74a773ffadb5fe3b26ae211e682b263c19db
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.adoc
CHANGED
@@ -611,6 +611,25 @@ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
|
611
611
|
|
612
612
|
Any object that _is not_ the same type will have a `nil` value as shown in the last two examples. Two hashes with the same keys but defined in different order behave as if they had the same key order.
|
613
613
|
|
614
|
+
===== #fetch_deep
|
615
|
+
|
616
|
+
Fetches a nested value by combining the behavior of `#fetch` and `#dig` into a single method. This works with nested arrays too. Examples:
|
617
|
+
|
618
|
+
[source,ruby]
|
619
|
+
----
|
620
|
+
demo = {a: {b: {c: [1, 2, 3]}}}
|
621
|
+
|
622
|
+
demo.fetch_deep :a # {b: {c: [1, 2, 3]}}
|
623
|
+
demo.fetch_deep :a, :b # {c: [1, 2, 3]}
|
624
|
+
demo.fetch_deep :a, :b, :c # [1, 2, 3]
|
625
|
+
demo.fetch_deep :a, :b, :c, 1 # 2
|
626
|
+
demo.fetch_deep(:a, :x, default: "fallback") # "fallback"
|
627
|
+
demo.fetch_deep(:a, :x) { "fallback" } # "fallback"
|
628
|
+
demo.fetch_deep # key not found: nil (KeyError)
|
629
|
+
demo.fetch_deep :a, :bogus # key not found: :bogus (KeyError)
|
630
|
+
demo.fetch_deep :a, :b, :c, :bogus # Unable to find :bogus in [1, 2, 3]. (KeyError)
|
631
|
+
----
|
632
|
+
|
614
633
|
===== #fetch_value
|
615
634
|
|
616
635
|
Fetches value for exiting or missing key. Behavior is identical to `#fetch` except when the value of
|
@@ -1049,26 +1068,34 @@ Pathname.pwd # "$HOME/demo" (Present Working Director
|
|
1049
1068
|
|
1050
1069
|
⚠️ This method is _not thread safe_ and suffers the same issues as found with native `Dir.chdir` functionality because the underlying native call is global. Use with care.
|
1051
1070
|
|
1052
|
-
===== #
|
1071
|
+
===== #clear
|
1053
1072
|
|
1054
|
-
|
1073
|
+
Removes all child directories and files from path while answering itself.
|
1055
1074
|
|
1056
1075
|
[source,ruby]
|
1057
1076
|
----
|
1058
|
-
|
1077
|
+
root = Pathname("demo")
|
1078
|
+
root.join("a/path/to/a.txt").touch_deep
|
1079
|
+
root.join("b.txt").touch
|
1080
|
+
root.clear
|
1081
|
+
|
1082
|
+
root.children # []
|
1083
|
+
root.clear # Pathname "demo"
|
1059
1084
|
----
|
1060
1085
|
|
1061
|
-
===== #
|
1086
|
+
===== #copy
|
1062
1087
|
|
1063
|
-
|
1064
|
-
directories no matter how deeply nested the file might be.
|
1088
|
+
Copies file from current location to new location while answering itself so it can be chained.
|
1065
1089
|
|
1066
1090
|
[source,ruby]
|
1067
1091
|
----
|
1068
|
-
Pathname("
|
1069
|
-
Pathname("a/b/c/d.txt").touch Time.now - 1 # Pathname("a/b/c/d.txt")
|
1092
|
+
Pathname("input.txt").copy Pathname("output.txt") # Pathname("input.txt")
|
1070
1093
|
----
|
1071
1094
|
|
1095
|
+
===== #deep_touch
|
1096
|
+
|
1097
|
+
⚠️ This method is deprecated and will be removed in Version 14.0.0. Please use `#touch_deep` instead.
|
1098
|
+
|
1072
1099
|
===== #delete
|
1073
1100
|
|
1074
1101
|
Deletes file or directory and answers itself so it can be chained.
|
@@ -1251,6 +1278,17 @@ Pathname("example.txt").touch # Pathname("example.txt")
|
|
1251
1278
|
Pathname("example.txt").touch Time.now - 1 # Pathname("example.txt")
|
1252
1279
|
----
|
1253
1280
|
|
1281
|
+
===== #touch_deep
|
1282
|
+
|
1283
|
+
Has all of the same functionality as the `#touch` method while being able to create ancestor
|
1284
|
+
directories no matter how deeply nested the path might be.
|
1285
|
+
|
1286
|
+
[source,ruby]
|
1287
|
+
----
|
1288
|
+
Pathname("a/b/c/d.txt").touch_deep # Pathname("a/b/c/d.txt")
|
1289
|
+
Pathname("a/b/c/d.txt").touch_deep Time.now - 1 # Pathname("a/b/c/d.txt")
|
1290
|
+
----
|
1291
|
+
|
1254
1292
|
===== #write
|
1255
1293
|
|
1256
1294
|
Writes to file and answers itself so it can be chained. See `IO.write` for details on additional
|
@@ -1410,6 +1448,30 @@ Answers a title string with proper capitalization of each word.
|
|
1410
1448
|
"ThisIsAnExample".titleize # "This Is An Example"
|
1411
1449
|
----
|
1412
1450
|
|
1451
|
+
===== #trim_end
|
1452
|
+
|
1453
|
+
Answers the trimmed end of a string (non-mutated) for given length with optional delimiter and/or overflow.
|
1454
|
+
|
1455
|
+
The delimiter is the second positional parameter (optional) and is `nil` by default. A custom string or regular expression can be used to customize behavior.
|
1456
|
+
|
1457
|
+
The trailer is an optional keyword parameter that is an ellipsis (i.e. `"..."`) by default. The trailer can be a custom or empty string. The string length of the trailer is added to the length of the string being trimmed, so keep this in mind when setting length.
|
1458
|
+
|
1459
|
+
[source,ruby]
|
1460
|
+
----
|
1461
|
+
demo = "It was the best of times"
|
1462
|
+
length = demo.length
|
1463
|
+
|
1464
|
+
demo.trim_end 9 # "It was..."
|
1465
|
+
demo.trim_end 12 # "It was th..."
|
1466
|
+
demo.trim_end length # "It was the best of times"
|
1467
|
+
demo.trim_end Float::INFINITY # "It was the best of times"
|
1468
|
+
demo.trim_end 12, " " # "It was..."
|
1469
|
+
demo.trim_end 12, /\s/ # "It was..."
|
1470
|
+
demo.trim_end 6, trailer: "" # "It was"
|
1471
|
+
demo.trim_end 16, trailer: "... (more)" # "It was... (more)"
|
1472
|
+
"demo".trim_end 3 # "..."
|
1473
|
+
----
|
1474
|
+
|
1413
1475
|
===== #truthy?
|
1414
1476
|
|
1415
1477
|
Answers if string is truthy.
|
@@ -1425,27 +1487,7 @@ Answers if string is truthy.
|
|
1425
1487
|
|
1426
1488
|
===== #truncate
|
1427
1489
|
|
1428
|
-
|
1429
|
-
|
1430
|
-
The delimiter is the second positional parameter (optional) and is `nil` by default. A custom string or regular expression can be used to customize truncation behavior.
|
1431
|
-
|
1432
|
-
The trailer is an optional keyword parameter that is an ellipsis (i.e. `"..."`) by default. The trailer can be a custom or empty string. The string length of the trailer is added to the length of the string being truncated, so keep this in mind when setting truncation length.
|
1433
|
-
|
1434
|
-
[source,ruby]
|
1435
|
-
----
|
1436
|
-
demo = "It was the best of times"
|
1437
|
-
length = demo.length
|
1438
|
-
|
1439
|
-
demo.truncate 9 # "It was..."
|
1440
|
-
demo.truncate 12 # "It was th..."
|
1441
|
-
demo.truncate length # "It was the best of times"
|
1442
|
-
demo.truncate Float::INFINITY # "It was the best of times"
|
1443
|
-
demo.truncate 12, " " # "It was..."
|
1444
|
-
demo.truncate 12, /\s/ # "It was..."
|
1445
|
-
demo.truncate 6, trailer: "" # "It was"
|
1446
|
-
demo.truncate 16, trailer: "... (more)" # "It was... (more)"
|
1447
|
-
"demo".truncate 3 # "..."
|
1448
|
-
----
|
1490
|
+
⚠️ This method is deprecated and will be removed in Version 14.0.0. Please use `#trim_end` instead.
|
1449
1491
|
|
1450
1492
|
===== #to_bool
|
1451
1493
|
|
@@ -1540,37 +1582,11 @@ Any object that _is not_ the same type will have a `nil` value as shown in the l
|
|
1540
1582
|
|
1541
1583
|
===== #merge
|
1542
1584
|
|
1543
|
-
|
1544
|
-
Works regardless of whether the struct is constructed with positional or keyword arguments.
|
1545
|
-
|
1546
|
-
[source,ruby]
|
1547
|
-
----
|
1548
|
-
example = Struct.new("Example", :a, :b, :c).new 1, 2, 3
|
1549
|
-
other = Struct.new("Other", :a, :b, :c).new 7, 8, 9
|
1550
|
-
|
1551
|
-
example.merge a: 10 # #<struct Struct::Example a=10, b=2, c=3>
|
1552
|
-
example.merge a: 10, c: 30 # #<struct Struct::Example a=10, b=2, c=30>
|
1553
|
-
example.merge a: 10, b: 20, c: 30 # #<struct Struct::Example a=10, b=20, c=30>
|
1554
|
-
example.merge other # #<struct Struct::Example a=7, b=8, c=9>
|
1555
|
-
example # #<struct Struct::Example a=1, b=2, c=3>
|
1556
|
-
----
|
1585
|
+
⚠️ This method is deprecated and will be removed in Version 14.0.0. Please use xref:_with[#with] instead.
|
1557
1586
|
|
1558
1587
|
===== #merge!
|
1559
1588
|
|
1560
|
-
|
1561
|
-
Works regardless of whether the struct is constructed with positional or keyword arguments.
|
1562
|
-
|
1563
|
-
[source,ruby]
|
1564
|
-
----
|
1565
|
-
example = Struct.new("Example", :a, :b, :c).new 1, 2, 3
|
1566
|
-
other = Struct.new("Other", :a, :b, :c).new 7, 8, 9
|
1567
|
-
|
1568
|
-
example.merge! a: 10 # #<struct Struct::Example a=10, b=2, c=3>
|
1569
|
-
example.merge! a: 10, c: 30 # #<struct Struct::Example a=10, b=2, c=30>
|
1570
|
-
example.merge! other # #<struct Struct::Example a=7, b=8, c=9>
|
1571
|
-
example.merge! a: 10, b: 20, c: 30 # #<struct Struct::Example a=10, b=20, c=30>
|
1572
|
-
example # #<struct Struct::Example a=10, b=20, c=30>
|
1573
|
-
----
|
1589
|
+
⚠️ This method is deprecated and will be removed in Version 14.0.0. Please use xref:_with_2[#with!] instead.
|
1574
1590
|
|
1575
1591
|
===== #transmute
|
1576
1592
|
|
@@ -1610,7 +1626,35 @@ a # #<struct Struct::A a=7, b=8, c=30>
|
|
1610
1626
|
|
1611
1627
|
===== #with
|
1612
1628
|
|
1613
|
-
|
1629
|
+
Allows you to use `Struct` and `Data` objects more interchangeably by merging multiple attributes without mutating itself. Supports any object that responds to `#to_h`. Works regardless of whether the struct is constructed with positional or keyword arguments.
|
1630
|
+
|
1631
|
+
[source,ruby]
|
1632
|
+
----
|
1633
|
+
example = Struct.new("Example", :a, :b, :c).new 1, 2, 3
|
1634
|
+
other = Struct.new("Other", :a, :b, :c).new 7, 8, 9
|
1635
|
+
|
1636
|
+
example.with a: 10 # #<struct Struct::Example a=10, b=2, c=3>
|
1637
|
+
example.with a: 10, c: 30 # #<struct Struct::Example a=10, b=2, c=30>
|
1638
|
+
example.with a: 10, b: 20, c: 30 # #<struct Struct::Example a=10, b=20, c=30>
|
1639
|
+
example.with other # #<struct Struct::Example a=7, b=8, c=9>
|
1640
|
+
example # #<struct Struct::Example a=1, b=2, c=3>
|
1641
|
+
----
|
1642
|
+
|
1643
|
+
===== #with!
|
1644
|
+
|
1645
|
+
Allows you to merge multiple attributes while mutating itself. Supports any object that responds to `#to_h`. Works regardless of whether the struct is constructed with positional or keyword arguments.
|
1646
|
+
|
1647
|
+
[source,ruby]
|
1648
|
+
----
|
1649
|
+
example = Struct.new("Example", :a, :b, :c).new 1, 2, 3
|
1650
|
+
other = Struct.new("Other", :a, :b, :c).new 7, 8, 9
|
1651
|
+
|
1652
|
+
example.with! a: 10 # #<struct Struct::Example a=10, b=2, c=3>
|
1653
|
+
example.with! a: 10, c: 30 # #<struct Struct::Example a=10, b=2, c=30>
|
1654
|
+
example.with! other # #<struct Struct::Example a=7, b=8, c=9>
|
1655
|
+
example.with! a: 10, b: 20, c: 30 # #<struct Struct::Example a=10, b=20, c=30>
|
1656
|
+
example # #<struct Struct::Example a=10, b=20, c=30>
|
1657
|
+
----
|
1614
1658
|
|
1615
1659
|
==== Symbol
|
1616
1660
|
|
data/lib/refinements/hash.rb
CHANGED
@@ -49,6 +49,16 @@ module Refinements
|
|
49
49
|
each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
|
50
50
|
end
|
51
51
|
|
52
|
+
def fetch_deep(*keys, default: NilClass, &)
|
53
|
+
keys.reduce fallback(keys.shift, default, &) do |value, key|
|
54
|
+
unless value.is_a?(::Hash) || (value.is_a?(::Array) && key.is_a?(::Integer))
|
55
|
+
fail KeyError, "Unable to find #{key.inspect} in #{value.inspect}."
|
56
|
+
end
|
57
|
+
|
58
|
+
default == NilClass ? value.fetch(key, &) : value.fetch(key, default)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
52
62
|
def fetch_value(key, *default, &)
|
53
63
|
fetch(key, *default, &) || (yield if block_given?) || default.first
|
54
64
|
end
|
@@ -107,6 +117,10 @@ module Refinements
|
|
107
117
|
result = merge(other.to_h) { |_, one, two| [one, two].uniq }
|
108
118
|
result.select { |_, diff| diff.size == 2 }
|
109
119
|
end
|
120
|
+
|
121
|
+
def fallback(key, default, &)
|
122
|
+
default == NilClass ? fetch(key, &) : fetch(key, default)
|
123
|
+
end
|
110
124
|
end
|
111
125
|
end
|
112
126
|
end
|
data/lib/refinements/pathname.rb
CHANGED
@@ -30,13 +30,20 @@ module Refinements
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
def clear = children.each(&:rmtree) && self
|
34
|
+
|
33
35
|
def copy to
|
34
36
|
destination = to.directory? ? to.join(basename) : to
|
35
|
-
|
37
|
+
::IO.copy_stream self, destination
|
36
38
|
self
|
37
39
|
end
|
38
40
|
|
39
|
-
def deep_touch(...)
|
41
|
+
def deep_touch(...)
|
42
|
+
warn "`#{self.class}##{__method__}` is deprecated, use `#touch_deep` instead.",
|
43
|
+
category: :deprecated
|
44
|
+
|
45
|
+
touch_deep(...)
|
46
|
+
end
|
40
47
|
|
41
48
|
def delete = super && self
|
42
49
|
|
@@ -78,6 +85,8 @@ module Refinements
|
|
78
85
|
self
|
79
86
|
end
|
80
87
|
|
88
|
+
def touch_deep(...) = make_ancestors.touch(...)
|
89
|
+
|
81
90
|
def write content, offset: nil, **options
|
82
91
|
super content, offset, **options
|
83
92
|
self
|
data/lib/refinements/string.rb
CHANGED
@@ -62,9 +62,7 @@ module Refinements
|
|
62
62
|
.then { |parts| combine parts, :up, "/" }
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
|
67
|
-
def truncate to, delimiter = nil, trailer: "..."
|
65
|
+
def trim_end to, delimiter = nil, trailer: "..."
|
68
66
|
return dup if length <= to
|
69
67
|
|
70
68
|
offset = to - trailer.length
|
@@ -72,6 +70,15 @@ module Refinements
|
|
72
70
|
"#{self[...maximum]}#{trailer}"
|
73
71
|
end
|
74
72
|
|
73
|
+
def truthy? = %w[true yes on t y 1].include? downcase.strip
|
74
|
+
|
75
|
+
def truncate(...)
|
76
|
+
warn "`#{self.class}##{__method__}` is deprecated, use `#trim_end` instead.",
|
77
|
+
category: :deprecated
|
78
|
+
|
79
|
+
trim_end(...)
|
80
|
+
end
|
81
|
+
|
75
82
|
# rubocop:disable Naming/PredicateMethod
|
76
83
|
def to_bool
|
77
84
|
warn "`#{self.class}##{__method__}` is deprecated, use `#truthy?` or `#falsey?` instead.",
|
data/lib/refinements/struct.rb
CHANGED
@@ -8,11 +8,18 @@ module Refinements
|
|
8
8
|
refine ::Struct do
|
9
9
|
import_methods Shared::Diff
|
10
10
|
|
11
|
-
def merge(...)
|
11
|
+
def merge(...)
|
12
|
+
warn "`#{self.class}##{__method__}` is deprecated, use `#with` instead.",
|
13
|
+
category: :deprecated
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
with(...)
|
16
|
+
end
|
17
|
+
|
18
|
+
def merge!(...)
|
19
|
+
warn "`#{self.class}##{__method__}` is deprecated, use `#with!` instead.",
|
20
|
+
category: :deprecated
|
21
|
+
|
22
|
+
with!(...)
|
16
23
|
end
|
17
24
|
|
18
25
|
def transmute(...) = dup.transmute!(...)
|
@@ -22,7 +29,12 @@ module Refinements
|
|
22
29
|
merge! object.to_h.slice(*mapping.keys).transform_keys!(mapping)
|
23
30
|
end
|
24
31
|
|
25
|
-
|
32
|
+
def with(...) = dup.with!(...)
|
33
|
+
|
34
|
+
def with! object = nil
|
35
|
+
to_h.merge!(**object.to_h).each { |key, value| self[key] = value }
|
36
|
+
self
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
data/refinements.gemspec
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: refinements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 13.
|
4
|
+
version: 13.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
requirements: []
|
91
|
-
rubygems_version: 3.
|
91
|
+
rubygems_version: 3.7.1
|
92
92
|
specification_version: 4
|
93
93
|
summary: A collection of core object refinements.
|
94
94
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|