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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +91 -15
- data/lib/refinements/hash.rb +44 -13
- data/lib/refinements/pathname.rb +7 -2
- 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: d986dc181b2c378adc82cc89841387a47286f58f5a3c87bb94d81d951934ab86
|
|
4
|
+
data.tar.gz: 5e4608408e3f89bf4ed72097deec34b0744b5ac939d837eecbd5b887616b9c83
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 = {
|
|
537
|
+
example = {demo: {one: "One"}}
|
|
538
538
|
|
|
539
|
-
example.deep_merge
|
|
540
|
-
example
|
|
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
|
|
1066
|
-
custom = current.join("test").
|
|
1067
|
-
custom.change_dir
|
|
1068
|
-
current.change_dir
|
|
1069
|
-
custom.change_dir { "example" }
|
|
1070
|
-
custom.change_dir { |path| path }
|
|
1071
|
-
Pathname.pwd
|
|
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").
|
|
1254
|
-
Pathname("/test").remove_dir
|
|
1255
|
-
Pathname("/test").remove_dir.remove_dir
|
|
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
|
data/lib/refinements/hash.rb
CHANGED
|
@@ -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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
|
117
|
-
|
|
118
|
-
|
|
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, &)
|
data/lib/refinements/pathname.rb
CHANGED
|
@@ -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.
|
|
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
|
|
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
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.
|
|
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.
|
|
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
|