refinements 14.5.0 → 14.6.1

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: 730d2c8e3fd694a24d88c05755eec1599b26002fd7317131c795e5752ed16fb5
4
- data.tar.gz: 5611e41668a0570ae5944569bee6b54e7b47176a37831ba8817c20c63edb2840
3
+ metadata.gz: d986dc181b2c378adc82cc89841387a47286f58f5a3c87bb94d81d951934ab86
4
+ data.tar.gz: 5e4608408e3f89bf4ed72097deec34b0744b5ac939d837eecbd5b887616b9c83
5
5
  SHA512:
6
- metadata.gz: 4314a271e2c4ab6f0c5d4d0f2e4c56d13b68b4e7d5f11b46ffb3e477f1a7770d44c0a670e7fee640cec6f2df74daee191eaf5b764a379b7c17a9e0011328fd20
7
- data.tar.gz: 1eca09b429c622b3365b6cf5d2905313cebffa45264ac25684bba65332f70e58934c301655ee6651f96a3c5c59df526aeeb50e4aa5e02e126f0db1f7c8795d15
6
+ metadata.gz: 9a0628a9e07d1550af4e03bb39d80fe0494b429a58fb097095b46e25e93560bc4ff71ee79a4519709e3db6d036e8001f9c78c2551a6d3be38fa9d6ceee31396d
7
+ data.tar.gz: 3cd5c78b4a678c7b826366a8c61fcdab222a45c9b8dd103dd6e6f9529bc923c292181bf8ce698a86a6ac23f5bd17ddc9e707da9537dcc817f661e76c85ef253a
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -463,10 +463,10 @@ Any object that _is not_ the same type will have a `nil` value as shown in the l
463
463
 
464
464
  ===== .utc
465
465
 
466
- Answers new DateTime object for current UTC date/time.
467
-
468
466
  ⚠️ This method (and refinement) is deprecated and will be removed in the next major release.
469
467
 
468
+ Answers new DateTime object for current UTC date/time.
469
+
470
470
  [source,ruby]
471
471
  ----
472
472
  DateTime.utc # "#<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867000n),+0s,2299161j)>"
@@ -534,10 +534,34 @@ Merges deeply nested hashes together without mutating itself.
534
534
 
535
535
  [source,ruby]
536
536
  ----
537
- example = {a: "A", b: {one: "One", two: "Two"}}
537
+ example = {demo: {one: "One"}}
538
538
 
539
- example.deep_merge b: {one: 1} # {a: "A", b: {one: 1, two: "Two"}}
540
- example # {a: "A", b: {one: "One", two: "Two"}}
539
+ example.deep_merge demo: {one: 1} # {demo: {one: 1}}
540
+ example # {demo: {one: "One"}}
541
+ ----
542
+
543
+ Nested arrays are concatenated:
544
+
545
+ [source,ruby]
546
+ ----
547
+ {demo: [1, 2]}.deep_merge(demo: [3, 4])
548
+ # {demo: [1, 2, 3, 4]}
549
+ ----
550
+
551
+ Arrays are concatenated by index so ensure both arrays are in the same order when needing to merge nested arrays and/or hashes. If the other array has more elements which are not arrays or hashes, they will be appended. Example:
552
+
553
+ [source,ruby]
554
+ ----
555
+ {demo: [1, [2, 3], {a: 1}]}.deep_merge(demo: [:a, [4, 5], {a: :one, b: :two}, 6])
556
+ # {
557
+ # demo: [
558
+ # 1,
559
+ # [2, 3, 4, 5],
560
+ # {a: :one, b: :two},
561
+ # :a
562
+ # 6
563
+ # ]
564
+ # }
541
565
  ----
542
566
 
543
567
  ===== #deep_merge!
@@ -552,6 +576,8 @@ example.deep_merge! b: {one: 1} # {a: "A", b: {one: 1, two: "Two"}}
552
576
  example # {a: "A", b: {one: 1, two: "Two"}}
553
577
  ----
554
578
 
579
+ For more example, see `+#deep_merge+` above.
580
+
555
581
  ===== #deep_stringify_keys
556
582
 
557
583
  Answers string keys of a nested hash without mutating itself. Does not handle nested arrays, though.
@@ -616,6 +642,52 @@ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
616
642
 
617
643
  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.
618
644
 
645
+ ===== #expand_keys
646
+
647
+ Allows you to expand flat keys into a nested hash. This is the reverse of `+#flatten_keys+`.
648
+
649
+ [source,ruby]
650
+ ----
651
+ {"a.a" => 0, "a.b.one" => 1, "a.b.two" => 2}.expand_keys
652
+
653
+ # {
654
+ # "a" => {
655
+ # "a" => 0,
656
+ # "b" => {
657
+ # "one" => 1,
658
+ # "two" => 2
659
+ # }
660
+ # }
661
+ # }
662
+
663
+ {"a_a" => 0, "a_b_one" => 1, "a_b_two" => 2}.expand_keys delimiter: "_"
664
+
665
+ # {
666
+ # "a" => {
667
+ # "a" => 0,
668
+ # "b" => {
669
+ # "one" => 1,
670
+ # "two" => 2
671
+ # }
672
+ # }
673
+ # }
674
+ ----
675
+
676
+ Parent values -- which are not hashes -- are ignored when a nested child hash exists. Example:
677
+
678
+ [source,ruby]
679
+ ----
680
+ {"a" => 0, "a.b" => 1, "a.b.one" => :test}.expand_keys
681
+
682
+ # {
683
+ # "a" => {
684
+ # "b" => {
685
+ # "one" => :test
686
+ # }
687
+ # }
688
+ # }
689
+ ----
690
+
619
691
  ===== #fetch_deep
620
692
 
621
693
  Fetches a nested value by combining the behavior of `#fetch` and `#dig` into a single method. This works with nested arrays too. Examples:
@@ -853,6 +925,8 @@ example # {name: "Jayne", email: "jd@example.com"}
853
925
 
854
926
  ===== #use
855
927
 
928
+ ⚠️ This method is deprecated and will be removed in the next major release.
929
+
856
930
  Uses the hash's keys as block arguments where the value of the block argument is equal to the value of the key found within the hash. Works best with hashes that use symbols for keys but falls back to string keys when symbol keys can't be found.
857
931
 
858
932
  [source,ruby]
@@ -1062,13 +1136,13 @@ link:https://rubyapi.org/o/Dir.chdir#method-c-chdir[Dir.chdir] for details.
1062
1136
 
1063
1137
  [source,ruby]
1064
1138
  ----
1065
- current = Pathname.pwd # "$HOME/demo" (Present Working Directory)
1066
- custom = current.join("test").make_dir # Pathname "$HOME/demo/test"
1067
- custom.change_dir # "$HOME/demo/test" (Present Working Directory)
1068
- current.change_dir # "$HOME/demo" (Present Working Directory)
1069
- custom.change_dir { "example" } # "example"
1070
- custom.change_dir { |path| path } # Pathname "$HOME/demo/test"
1071
- Pathname.pwd # "$HOME/demo" (Present Working Directory)
1139
+ current = Pathname.pwd # "$HOME/demo" (Present Working Directory)
1140
+ custom = current.join("test").mkpath # Pathname "$HOME/demo/test"
1141
+ custom.change_dir # "$HOME/demo/test" (Present Working Directory)
1142
+ current.change_dir # "$HOME/demo" (Present Working Directory)
1143
+ custom.change_dir { "example" } # "example"
1144
+ custom.change_dir { |path| path } # Pathname "$HOME/demo/test"
1145
+ Pathname.pwd # "$HOME/demo" (Present Working Directory)
1072
1146
  ----
1073
1147
 
1074
1148
  ⚠️ 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.
@@ -1203,6 +1277,8 @@ Pathname("/one/two").exist? # false
1203
1277
 
1204
1278
  ===== #make_dir
1205
1279
 
1280
+ ⚠️ This method is deprecated and will be removed in the next major release.
1281
+
1206
1282
  Provides alternative `#mkdir` behavior by always answering itself (even when directory exists) and
1207
1283
  not throwing errors when directory does exist in order to ensure the pathname can be chained.
1208
1284
 
@@ -1250,9 +1326,9 @@ not throwing errors when directory does exist in order to ensure the pathname ca
1250
1326
 
1251
1327
  [source,ruby]
1252
1328
  ----
1253
- Pathname("/test").make_dir.remove_dir.exist? # false
1254
- Pathname("/test").remove_dir # Pathname("/test")
1255
- Pathname("/test").remove_dir.remove_dir # Pathname("/test")
1329
+ Pathname("/test").mkpath.remove_dir.exist? # false
1330
+ Pathname("/test").remove_dir # Pathname("/test")
1331
+ Pathname("/test").remove_dir.remove_dir # Pathname("/test")
1256
1332
  ----
1257
1333
 
1258
1334
  ===== #rewrite
@@ -4,6 +4,7 @@ require "refinements/shared/many"
4
4
 
5
5
  module Refinements
6
6
  # Provides additional enhancements to the Hash primitive.
7
+ # rubocop:todo-next Metrics/ModuleLength
7
8
  module Hash
8
9
  refine ::Hash.singleton_class do
9
10
  def infinite = new { |nascence, lacuna| nascence[lacuna] = new(&nascence.default_proc) }
@@ -21,20 +22,20 @@ module Refinements
21
22
  compact!
22
23
  end
23
24
 
24
- def deep_merge other
25
- clazz = self.class
25
+ def deep_merge(other, &) = dup.deep_merge!(other, &)
26
26
 
27
- merge other do |_key, this_value, other_value|
28
- if this_value.is_a?(clazz) && other_value.is_a?(clazz)
29
- this_value.deep_merge other_value
30
- else
31
- other_value
27
+ def deep_merge!(other, &)
28
+ klass = self.class
29
+
30
+ merge! other do |key, first, second|
31
+ if first.is_a?(klass) && second.is_a?(klass) then first.deep_merge(second, &)
32
+ elsif first.is_a?(::Array) && second.is_a?(::Array) then deep_concat(first, second, &)
33
+ elsif block_given? then yield key, first, second
34
+ else second
32
35
  end
33
36
  end
34
37
  end
35
38
 
36
- def deep_merge!(other) = replace(deep_merge(other))
37
-
38
39
  def deep_stringify_keys = recurse(&:stringify_keys)
39
40
 
40
41
  def deep_stringify_keys! = replace(deep_stringify_keys)
@@ -44,11 +45,18 @@ module Refinements
44
45
  def deep_symbolize_keys! = replace(deep_symbolize_keys)
45
46
 
46
47
  def diff other
47
- return differences_from other if other.is_a?(self.class) && keys.sort! == other.keys.sort!
48
+ return diff_array other if other.is_a?(self.class) && keys.sort! == other.keys.sort!
48
49
 
49
50
  each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
50
51
  end
51
52
 
53
+ def expand_keys delimiter: "."
54
+ each.with_object({}) do |(key, value), all|
55
+ parts = String(key).split(delimiter).reverse
56
+ all.deep_merge! parts.reduce(value) { |accumulator, part| {part => accumulator} }
57
+ end
58
+ end
59
+
52
60
  def fetch_deep(*keys, default: NilClass, &)
53
61
  keys.reduce fallback(keys.shift, default, &) do |value, key|
54
62
  unless value.is_a?(::Hash) || (value.is_a?(::Array) && key.is_a?(::Integer))
@@ -104,6 +112,10 @@ module Refinements
104
112
  end
105
113
 
106
114
  def use &block
115
+ warn "`#{self.class}##{__method__}` is deprecated and will be removed " \
116
+ "in the next major version.",
117
+ category: :deprecated
118
+
107
119
  return [] unless block
108
120
 
109
121
  block.parameters
@@ -113,9 +125,28 @@ module Refinements
113
125
 
114
126
  private
115
127
 
116
- def differences_from other
117
- result = merge(other.to_h) { |_, one, two| [one, two].uniq }
118
- result.select { |_, diff| diff.size == 2 }
128
+ def deep_concat(original, second, &)
129
+ first = original.dup
130
+ klass = self.class
131
+
132
+ second.each.with_index do |second_item, index|
133
+ first_item = first[index]
134
+
135
+ if first_item.is_a?(klass) && second_item.is_a?(klass)
136
+ first[index] = first_item.deep_merge!(second_item, &)
137
+ elsif second_item.is_a? ::Array
138
+ first[index] = deep_concat(first_item, second_item, &)
139
+ else
140
+ first.append(second_item).uniq!
141
+ end
142
+ end
143
+
144
+ first
145
+ end
146
+
147
+ def diff_array other
148
+ merged = merge(other.to_h) { |_, one, two| [one, two].uniq }
149
+ merged.select { |_, diff| diff.size == 2 }
119
150
  end
120
151
 
121
152
  def fallback(key, default, &)
@@ -46,7 +46,7 @@ module Refinements
46
46
  glob(pattern, flag).select(&:directory?)
47
47
  end
48
48
 
49
- def empty = file? ? (truncate(0) and self) : rmtree.make_dir
49
+ def empty = file? ? (truncate(0) and self) : rmtree.mkpath
50
50
 
51
51
  def extensions = basename.to_s.split(/(?=\.)+/).tap(&:shift)
52
52
 
@@ -59,7 +59,12 @@ module Refinements
59
59
  self
60
60
  end
61
61
 
62
- def make_dir = exist? ? self : (mkdir and self)
62
+ def make_dir
63
+ warn "`#{self.class}##{__method__}` is deprecated, use `mkpath` instead.",
64
+ category: :deprecated
65
+
66
+ mkpath
67
+ end
63
68
 
64
69
  def name = basename extname
65
70
 
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 = "14.5.0"
5
+ spec.version = "14.6.1"
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: 14.5.0
4
+ version: 14.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  requirements: []
92
- rubygems_version: 4.0.21
92
+ rubygems_version: 4.0.23
93
93
  specification_version: 4
94
94
  summary: A collection of core object refinements.
95
95
  test_files: []
metadata.gz.sig CHANGED
Binary file