refinements 11.0.1 → 11.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efdcd2042bcfde5031fad3d0049e01fc4e1ad23a9d4841ee601fdcb02a96d3af
4
- data.tar.gz: 55fac5447439c53705870a9409268e96aaf633e7a420f9d4678257f9b68f078d
3
+ metadata.gz: 91fae4e74017d86d0ca24e153dc7210fd9503276ccdf79da032e0f8f8ee2d181
4
+ data.tar.gz: eeea2c49941fe6508e9e4aab89aa42f38c2e23efd48b4f5381d4487a08061e3b
5
5
  SHA512:
6
- metadata.gz: 81949b0fb95b4aca53d6fd88f51d8cb4f0c8738bbb3eac83816880ff6b479ac86228847dd6660d8a99a861c5e3aee6e6985a0628764af037b328db55422cc7fb
7
- data.tar.gz: 6b40c6be0c5cc6304366fe60c8df54bca9e3ab366338f45308b2267f9a81f6adb123002740feb933af3313a0349a9a5035c39525c0b90d48f875842fefd0c3cf
6
+ metadata.gz: '08e77b3c0837d2158593f431a6cdd427cdc7cf9a1605178c0762444549b08807e3f3890cd7c578a8bc429d453b8961d38649a412b4616ea92889f745a721bc1f'
7
+ data.tar.gz: 20525ddb58f09cb45d4fc39fe652d0790b156f387bea40fe0f6574be0d396d8607cc6e9f692a6e6feee78f8608b102aaab5d9219ef6f4d43dcdd5e73e8ad4957
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -14,6 +14,7 @@ Enhances the following objects:
14
14
 
15
15
  * Array
16
16
  * BigDecimal
17
+ * Data
17
18
  * DateTime
18
19
  * Hash
19
20
  * IO
@@ -78,6 +79,7 @@ gem "refinements", require: false
78
79
  ----
79
80
  require "refinements/arrays"
80
81
  require "refinements/big_decimals"
82
+ require "refinements/data"
81
83
  require "refinements/date_times"
82
84
  require "refinements/hashes"
83
85
  require "refinements/ios"
@@ -100,6 +102,7 @@ refinement(s):
100
102
  class Example
101
103
  using Refinements::Arrays
102
104
  using Refinements::BigDecimals
105
+ using Refinements::Data
103
106
  using Refinements::DateTimes
104
107
  using Refinements::Hashes
105
108
  using Refinements::IOs
@@ -184,9 +187,9 @@ Answers the first element which evaluates to true from a filtered collection.
184
187
  [source,ruby]
185
188
  ----
186
189
  handlers = [
187
- ->(object) { object if object == :b },
190
+ -> object { object if object == :b },
188
191
  proc { false },
189
- ->(object) { object if object == :a }
192
+ -> object { object if object == :a }
190
193
  ]
191
194
 
192
195
  handlers.filter_find # Enumerator::Lazy
@@ -206,7 +209,7 @@ Adds given array or elements without mutating itself.
206
209
 
207
210
  ===== #intersperse
208
211
 
209
- Inserts additional elements or an array between all members of given array.
212
+ Inserts additional elements, or an array, between all members of given array.
210
213
 
211
214
  [source,ruby]
212
215
  ----
@@ -234,11 +237,13 @@ Answers the maximum extracted value from a collection of objects.
234
237
 
235
238
  [source,ruby]
236
239
  ----
237
- Point = Struct.new :x, :y
240
+ Point = Data.define :x, :y
238
241
  points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
239
242
 
240
- points.maximum(:x) # 2
241
- points.maximum(:y) # 3
243
+ points.maximum :x # 2
244
+ points.maximum :y # 3
245
+ points.maximum :z # undefined method `z' for #<data Point x=1, y=2> (NoMethodError)
246
+ [].maximum :x # nil
242
247
  ----
243
248
 
244
249
  ===== #mean
@@ -259,11 +264,13 @@ Answers the minimum extracted value from a collection of objects.
259
264
 
260
265
  [source,ruby]
261
266
  ----
262
- Point = Struct.new :x, :y
267
+ Point = Data.define :x, :y
263
268
  points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
264
269
 
265
- points.minimum(:x) # 0
266
- points.minimum(:y) # 1
270
+ points.minimum :x # 0
271
+ points.minimum :y # 1
272
+ points.minimum :z # undefined method `z' for #<data Point x=1, y=2> (NoMethodError)
273
+ [].minimum :x # nil
267
274
  ----
268
275
 
269
276
  ===== #pad
@@ -289,7 +296,7 @@ array = [{name: "a", label: "A"}, {name: "b", label: "B"}, {name: "c", label: "C
289
296
  array.pick :name # "a"
290
297
  array.pick :name, :label # ["a", "A"]
291
298
  array.pick # nil
292
- [].pick(:other) # nil
299
+ [].pick :other # nil
293
300
  ----
294
301
 
295
302
  ===== #pluck
@@ -312,10 +319,10 @@ Answers mutated array where an element -- at a specific index -- is replaced by
312
319
 
313
320
  [source,ruby]
314
321
  ----
315
- %i[a b c].replace_at(0, :x) # [:x, :b, :c]
316
- %i[a b c].replace_at(1, :x) # [:a, :x, :c]
317
- %i[a b c].replace_at(1, :x, :y) # [:a, :x, :y, :c]
318
- %i[a b c].replace_at(-1, :x) # [:a, :b, :x]
322
+ %i[a b c].replace_at 0, :x # [:x, :b, :c]
323
+ %i[a b c].replace_at 1, :x # [:a, :x, :c]
324
+ %i[a b c].replace_at 1, :x, :y # [:a, :x, :y, :c]
325
+ %i[a b c].replace_at -1, :x # [:a, :b, :x]
319
326
  ----
320
327
 
321
328
  ===== #ring
@@ -397,6 +404,28 @@ Allows one to inspect a big decimal with numeric representation.
397
404
  BigDecimal.new("5.0E-10").inspect # "#<BigDecimal:3fd3d458fe84 0.0000000005>"
398
405
  ----
399
406
 
407
+ ==== Data
408
+
409
+ ===== #diff
410
+
411
+ Allows you to obtain the differences between two objects.
412
+
413
+ [source,ruby]
414
+ ----
415
+ implementation = Data.define :a, :b, :c
416
+
417
+ one = implementation.new a: 1, b: 2, c: 3
418
+ two = implementation.new a: 3, b: 2, c: 1
419
+ three = Data.define(:x, :y).new x: 1, y: 2
420
+
421
+ one.diff one # {}
422
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
423
+ one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
424
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
425
+ ----
426
+
427
+ Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
428
+
400
429
  ==== DateTime
401
430
 
402
431
  ===== .utc
@@ -532,6 +561,26 @@ example.deep_symbolize_keys! # {a: {b: 1}}
532
561
  example # {a: {b: 1}}
533
562
  ----
534
563
 
564
+ ===== #diff
565
+
566
+ Allows you to obtain the differences between two objects.
567
+
568
+ [source,ruby]
569
+ ----
570
+ one = {a: 1, b: 2, c: 3}
571
+ two = {a: 3, b: 2, c: 1}
572
+ three = {c: 3, b: 2, a: 1}
573
+ four = Data.define(:x, :y).new x: 1, y: 2
574
+
575
+ one.diff one # {}
576
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
577
+ one.diff three # {}
578
+ one.diff four # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
579
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
580
+ ----
581
+
582
+ 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.
583
+
535
584
  ===== #fetch_value
536
585
 
537
586
  Fetches value for exiting or missing key. Behavior is identical to `#fetch` except when the value of
@@ -751,12 +800,12 @@ Answers full stream by rewinding to beginning of stream and reading all content.
751
800
  io = IO.new IO.sysopen(Pathname("demo.txt").to_s, "w+")
752
801
  io.write "This is a demo."
753
802
 
754
- io.reread # "This is a demo."
755
- io.reread 4 # "This"
803
+ io.reread # "This is a demo."
804
+ io.reread 4 # "This"
756
805
 
757
806
  buffer = "".dup
758
- io.reread(buffer: buffer) # "This is a demo."
759
- buffer # "This is a demo."
807
+ io.reread(buffer:) # "This is a demo."
808
+ buffer # "This is a demo."
760
809
  ----
761
810
 
762
811
  ===== #squelch
@@ -784,17 +833,17 @@ Answers previously written content by rewinding to beginning of device.
784
833
  # With File.
785
834
  device = Logger::LogDevice.new "test.log"
786
835
  device.write "Test."
787
- device.reread # "Test."
836
+ device.reread # "Test."
788
837
 
789
838
  # With StringIO.
790
839
  device = Logger::LogDevice.new StringIO.new
791
840
  device.write "Test."
792
- device.reread # "Test."
841
+ device.reread # "Test."
793
842
 
794
843
  # With STDOUT.
795
844
  device = Logger::LogDevice.new $stdout
796
845
  device.write "Test."
797
- device.reread # ""
846
+ device.reread # ""
798
847
  ----
799
848
 
800
849
  ==== Logger
@@ -808,17 +857,17 @@ Answers previously written content by rewinding to beginning of log.
808
857
  # With File.
809
858
  logger = Logger.new "test.log"
810
859
  logger.write "Test."
811
- logger.reread # "Test."
860
+ logger.reread # "Test."
812
861
 
813
862
  # With StringIO.
814
863
  logger = Logger.new StringIO.new
815
864
  logger.write "Test."
816
- logger.reread # "Test."
865
+ logger.reread # "Test."
817
866
 
818
867
  # With STDOUT.
819
868
  logger = Logger.new $stdout
820
869
  logger.write "Test."
821
- logger.reread # ""
870
+ logger.reread # ""
822
871
  ----
823
872
 
824
873
  ===== #any
@@ -846,7 +895,7 @@ construct a valid path.
846
895
 
847
896
  [source,ruby]
848
897
  ----
849
- Pathname(nil) # Pathname("")
898
+ Pathname nil # Pathname("")
850
899
  ----
851
900
 
852
901
  ===== .home
@@ -972,9 +1021,9 @@ Deletes a path prefix and answers new pathname.
972
1021
 
973
1022
  [source,ruby]
974
1023
  ----
975
- Pathname("a/path/example-test.rb").delete_prefix("example-") # Pathname("a/path/test.rb")
976
- Pathname("example-test.rb").delete_prefix("example-") # Pathname("test.rb")
977
- Pathname("example-test.rb").delete_prefix("miss") # Pathname("example-test.rb")
1024
+ Pathname("a/path/example-test.rb").delete_prefix "example-" # Pathname("a/path/test.rb")
1025
+ Pathname("example-test.rb").delete_prefix "example-" # Pathname("test.rb")
1026
+ Pathname("example-test.rb").delete_prefix "miss" # Pathname("example-test.rb")
978
1027
  ----
979
1028
 
980
1029
  ===== #delete_suffix
@@ -983,9 +1032,9 @@ Deletes a path suffix and answers new pathname.
983
1032
 
984
1033
  [source,ruby]
985
1034
  ----
986
- Pathname("a/path/test-example.rb").delete_suffix("-example") # Pathname("a/path/test.rb")
987
- Pathname("test-example.rb").delete_suffix("-example") # Pathname("test.rb")
988
- Pathname("test-example.rb").delete_suffix("miss") # Pathname("test-example.rb")
1035
+ Pathname("a/path/test-example.rb").delete_suffix "-example" # Pathname("a/path/test.rb")
1036
+ Pathname("test-example.rb").delete_suffix "-example" # Pathname("test.rb")
1037
+ Pathname("test-example.rb").delete_suffix "miss" # Pathname("test-example.rb")
989
1038
  ----
990
1039
 
991
1040
  ===== #directories
@@ -1039,10 +1088,10 @@ Same behavior as `String#gsub` but answers a path with patterns replaced with de
1039
1088
 
1040
1089
  [source,ruby]
1041
1090
  ----
1042
- Pathname("/a/path/some/path").gsub("path", "test")
1091
+ Pathname("/a/path/some/path").gsub "path", "test"
1043
1092
  # Pathname("/a/test/some/test")
1044
1093
 
1045
- Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test")
1094
+ Pathname("/%placeholder%/some/%placeholder%").gsub "%placeholder%", "test"
1046
1095
  # Pathname("/test/some/test")
1047
1096
  ----
1048
1097
 
@@ -1090,11 +1139,11 @@ Pathname("example.txt").name # Pathname("example")
1090
1139
 
1091
1140
  ===== #relative_parent
1092
1141
 
1093
- Answers relative path from parent directory. This is a complement to `#relative_path_from`.
1142
+ Answers relative path from parent directory. This complements: `#relative_path_from`.
1094
1143
 
1095
1144
  [source,ruby]
1096
1145
  ----
1097
- Pathname("/one/two/three").relative_parent("/one") # Pathname "two"
1146
+ Pathname("/one/two/three").relative_parent "/one" # Pathname "two"
1098
1147
  ----
1099
1148
 
1100
1149
  ===== #remove_dir
@@ -1333,8 +1382,8 @@ io.reread # "This is a test."
1333
1382
  io.reread 4 # "This"
1334
1383
 
1335
1384
  buffer = "".dup
1336
- io.reread(buffer: buffer) # "This is a test."
1337
- buffer # "This is a test."
1385
+ io.reread(buffer:) # "This is a test."
1386
+ buffer # "This is a test."
1338
1387
  ----
1339
1388
 
1340
1389
  ==== Struct
@@ -1355,6 +1404,26 @@ Example.with_positions 1, 2, 3 # #<struct a=1, b=2, c=3>
1355
1404
  Example.with_positions 1 # #<struct a=1, b=nil, c=nil>
1356
1405
  ----
1357
1406
 
1407
+ ===== #diff
1408
+
1409
+ Allows you to obtain the differences between two objects.
1410
+
1411
+ [source,ruby]
1412
+ ----
1413
+ implementation = Struct.new :a, :b, :c
1414
+
1415
+ one = implementation.new a: 1, b: 2, c: 3
1416
+ two = implementation.new a: 3, b: 2, c: 1
1417
+ three = Struct.new(:x, :y).new x: 1, y: 2
1418
+
1419
+ one.diff one # {}
1420
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
1421
+ one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
1422
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
1423
+ ----
1424
+
1425
+ Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
1426
+
1358
1427
  ===== #merge
1359
1428
 
1360
1429
  Merges multiple attributes without mutating itself and supports any object that responds to `#to_h`.
@@ -1393,8 +1462,7 @@ example # #<struct Struct::Example a=10, b=20, c=30>
1393
1462
 
1394
1463
  Transforms values without mutating itself. An optional hash can be supplied to target specific
1395
1464
  attributes. In the event that a block isn't supplied, the struct will answer itself since there is
1396
- nothing to operate on. Behavior is the same regardless of whether the struct is constructed using
1397
- positional or keyword arguments. Works regardless of whether the struct is constructed with
1465
+ nothing to operate on. Works regardless of whether the struct is constructed with
1398
1466
  positional or keyword arguments.
1399
1467
 
1400
1468
  [source,ruby]
@@ -1412,8 +1480,7 @@ example # #<struct Str
1412
1480
 
1413
1481
  Transforms values while mutating itself. An optional hash can be supplied to target specific
1414
1482
  attributes. In the event that a block isn't supplied, the struct will answer itself since there is
1415
- nothing to operate on. Behavior is the same regardless of whether the struct is constructed using
1416
- positional or keyword arguments. Works regardless of whether the struct is constructed with
1483
+ nothing to operate on. Works regardless of whether the struct is constructed with
1417
1484
  positional or keyword arguments.
1418
1485
 
1419
1486
  [source,ruby]
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/shared/values/diff"
4
+
5
+ module Refinements
6
+ # Provides additional enhancements to the Struct primitive.
7
+ module Data
8
+ refine ::Data do
9
+ import_methods Shared::Values::Diff
10
+ end
11
+ end
12
+ end
@@ -45,7 +45,13 @@ module Refinements
45
45
 
46
46
  def deep_symbolize_keys! = replace(deep_symbolize_keys)
47
47
 
48
- def fetch_value(key, *default_value, &) = fetch(key, *default_value, &) || default_value.first
48
+ def diff other
49
+ return differences_from other if other.is_a?(self.class) && keys.sort! == other.keys.sort!
50
+
51
+ each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
52
+ end
53
+
54
+ def fetch_value(key, *default, &) = fetch(key, *default, &) || default.first
49
55
 
50
56
  def flatten_keys prefix: nil, delimiter: "_"
51
57
  reduce({}) do |accumulator, (key, value)|
@@ -88,6 +94,13 @@ module Refinements
88
94
  .map { |(_type, key)| self[key] || self[key.to_s] }
89
95
  .then { |values| yield values }
90
96
  end
97
+
98
+ private
99
+
100
+ def differences_from other
101
+ result = merge(other.to_h) { |_, one, two| [one, two].uniq }
102
+ result.select { |_, diff| diff.size == 2 }
103
+ end
91
104
  end
92
105
  end
93
106
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Refinements
4
+ module Shared
5
+ module Values
6
+ # Provides shared whole value functionality for knowing the difference between two objects.
7
+ module Diff
8
+ def diff other
9
+ if other.is_a? self.class
10
+ to_h.merge(other.to_h) { |_, one, two| [one, two].uniq }
11
+ .select { |_, diff| diff.size == 2 }
12
+ else
13
+ to_h.each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "refinements/shared/values/diff"
4
+
3
5
  module Refinements
4
6
  # Provides additional enhancements to the Struct primitive.
5
7
  module Structs
@@ -8,6 +10,8 @@ module Refinements
8
10
  end
9
11
 
10
12
  refine Struct do
13
+ import_methods Shared::Values::Diff
14
+
11
15
  def merge(...) = dup.merge!(...)
12
16
 
13
17
  def merge! object = nil
data/lib/refinements.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "refinements/arrays"
4
4
  require "refinements/big_decimals"
5
+ require "refinements/data"
5
6
  require "refinements/date_times"
6
7
  require "refinements/hashes"
7
8
  require "refinements/ios"
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 = "11.0.1"
5
+ spec.version = "11.1.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: 11.0.1
4
+ version: 11.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -35,7 +35,7 @@ cert_chain:
35
35
  3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
36
36
  gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
37
37
  -----END CERTIFICATE-----
38
- date: 2023-06-19 00:00:00.000000000 Z
38
+ date: 2023-11-04 00:00:00.000000000 Z
39
39
  dependencies: []
40
40
  description:
41
41
  email:
@@ -51,6 +51,7 @@ files:
51
51
  - lib/refinements.rb
52
52
  - lib/refinements/arrays.rb
53
53
  - lib/refinements/big_decimals.rb
54
+ - lib/refinements/data.rb
54
55
  - lib/refinements/date_times.rb
55
56
  - lib/refinements/hashes.rb
56
57
  - lib/refinements/ios.rb
@@ -59,6 +60,7 @@ files:
59
60
  - lib/refinements/pathnames.rb
60
61
  - lib/refinements/shared/enumerables/many.rb
61
62
  - lib/refinements/shared/ios/reread.rb
63
+ - lib/refinements/shared/values/diff.rb
62
64
  - lib/refinements/string_ios.rb
63
65
  - lib/refinements/strings.rb
64
66
  - lib/refinements/structs.rb
@@ -90,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
92
  - !ruby/object:Gem::Version
91
93
  version: '0'
92
94
  requirements: []
93
- rubygems_version: 3.4.14
95
+ rubygems_version: 3.4.21
94
96
  signing_key:
95
97
  specification_version: 4
96
98
  summary: A collection of core Ruby object refinements.
metadata.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- #�],�Gi�ָ7G��ͣDw�>�' ���1D4z���+Ph(Y��&i�?���[�N)��3��b Gca0��OW��g+gV܈9e⍋dD��u�G��y��"ʥ��O�Bkl�a2m z���˗���Qx�
2
- � _8��� ��&�e�������KiEYm�ꏪgH[��?��I a��üwh!P��Nx{�bo��q�k]+8��}���֎)4�>���o�̂K�*�"���enT��Qe�W!2��C�~�z�t+���� o.(o���+�en:����T�
1
+ im����uV�?q��6
2
+ bM���e������T�`�!��9�u=�R��[m���E,�jq=7�a��EB\w8�\�����ɖv���U��(m��Z���ڌ#Np�'���f���,�=��.�x}8_����D����ce�:�(hr0���!uy ��z��#L[����x������^B���*K4ўS�+�S#�@��kR!9Z��[1���
3
+ �k�_�p�}˄��i|�a��!N!��΢hB��<0؛M�ri��?��U&u���̍9����i1?���9����V���D:�=1Y�X|�A6��v�c9�z��Y���u���u�.m�1e����nW��R�+�s���B���~�`l�h