refinements 13.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17368920f8d6281ee6bc0f02adcbc94715f3fb5dd05996f782bd34f2b4161f30
4
- data.tar.gz: 5ec445e38faecd830284b984b78536b2e4dd17a161e987a53cc629a71bafe84a
3
+ metadata.gz: c4f7a616f560224da3b786d73ad6f8f206c0aacba2b0701bbe91c5b8ecfec2c2
4
+ data.tar.gz: 9f166af1d48f1e00f0b8e3024f19fcfbd1cbbb8b8180bd798a69086455bc2079
5
5
  SHA512:
6
- metadata.gz: 942ba159dd0648e91ff4f81ca4f3e4dd785bbff7496062a82d223e4bf8f60eed4e118cb0754daec81b7bc90b7325cb83f4cc8db4de2e36352e4d48949e01ad3c
7
- data.tar.gz: 3f37095c6d6e497c9c52a7abb7692ad091bd70e63639a9329d0bf4b74cb653a37359812777579abdc85c7f0cee9b5d21b2a9457dc58b7dc2d67a38cb05d74f17
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
- ===== #copy
1071
+ ===== #clear
1053
1072
 
1054
- Copies file from current location to new location while answering itself so it can be chained.
1073
+ Removes all child directories and files from path while answering itself.
1055
1074
 
1056
1075
  [source,ruby]
1057
1076
  ----
1058
- Pathname("input.txt").copy Pathname("output.txt") # Pathname("input.txt")
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
- ===== #deep_touch
1086
+ ===== #copy
1062
1087
 
1063
- Has all of the same functionality as the `#touch` method while being able to create ancestor
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("a/b/c/d.txt").touch # Pathname("a/b/c/d.txt")
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
- Answers a truncated, non-mutated, string for given length with optional delimiter and/or overflow.
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
- Merges multiple attributes without mutating itself and supports any object that responds to `#to_h`.
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
- Merges multiple attributes while mutating itself and supports any object that responds to `#to_h`.
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
- An alias of `#merge` and identical in behavior (see `#merge` documentation for details). Allows you to use `Struct` and `Data` objects more interchangeably since they share the same method.
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
 
@@ -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
@@ -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(...) = make_ancestors.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
@@ -62,9 +62,7 @@ module Refinements
62
62
  .then { |parts| combine parts, :up, "/" }
63
63
  end
64
64
 
65
- def truthy? = %w[true yes on t y 1].include? downcase.strip
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.",
@@ -8,11 +8,18 @@ module Refinements
8
8
  refine ::Struct do
9
9
  import_methods Shared::Diff
10
10
 
11
- def merge(...) = dup.merge!(...)
11
+ def merge(...)
12
+ warn "`#{self.class}##{__method__}` is deprecated, use `#with` instead.",
13
+ category: :deprecated
12
14
 
13
- def merge! object = nil
14
- to_h.merge!(**object.to_h).each { |key, value| self[key] = value }
15
- self
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
- alias_method :with, :merge
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "refinements"
5
- spec.version = "13.4.0"
5
+ spec.version = "13.5.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/refinements"
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.0
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.7.0
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