refinements 11.0.0 → 11.1.0

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: 252744b620f3c79a0c38b635157f62fc9e48527701145e871de885c547b44b61
4
- data.tar.gz: 411b88c5cf6b9b95c59c43055b8a2402c95d9954b612837fce70a106c4c4a5f1
3
+ metadata.gz: 0ec4e17de3e050923d08c34123d8e8f2cf7096e66b3cf035c5fec870470de049
4
+ data.tar.gz: 8d5d5449055c76a8cb4675acc8ccbd2f9e46b4eb9986e29b04e548847f6d69b3
5
5
  SHA512:
6
- metadata.gz: 0c12fb201556e5949190657cd591b126115ba7efb9f14aec4aeb107455d7cd04676b0dd1cc05f84e9bdd8b7c61e2fbadbabe377b739ffd14a643c3d98d717068
7
- data.tar.gz: db75e0359afed8603daba0bae481b8e839b9d9ede700ef22bbcde22116e2a75b221b5d56d0381500ccf992f73c11cb7a4555823c4294b131077972800a03f3c1
6
+ metadata.gz: fe21be9b51f2616eeb94664a85006332dc1b00395cee44540a2adf9b5a08397636e22d35ca4d786887f2d6bfb287bcbca6aee54e89383b71f4976f1433980001
7
+ data.tar.gz: 5bc27d6026ce8ce38fe522929b54328c67445a7ed89f44ba57759a216b2f098c5fd18696bea14c0ab4719d953b59c6173ebff1e218d2d35b9bcfb9ebfdee43e8
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
@@ -289,7 +292,7 @@ array = [{name: "a", label: "A"}, {name: "b", label: "B"}, {name: "c", label: "C
289
292
  array.pick :name # "a"
290
293
  array.pick :name, :label # ["a", "A"]
291
294
  array.pick # nil
292
- [].pick(:test) # nil
295
+ [].pick(:other) # nil
293
296
  ----
294
297
 
295
298
  ===== #pluck
@@ -303,7 +306,7 @@ array = [{name: "a", label: "A"}, {name: "b", label: "B"}, {name: "c", label: "C
303
306
  array.pluck :name # ["a", "b", "c"]
304
307
  array.pluck :name, :label # [["a", "A"], ["b", "B"], ["c", "C"]]
305
308
  array.pluck # []
306
- [].pluck :test # []
309
+ [].pluck :other # []
307
310
  ----
308
311
 
309
312
  ===== #replace_at
@@ -365,25 +368,25 @@ Useful when building documentation, answering human readable error messages, etc
365
368
  [source,ruby]
366
369
  ----
367
370
  [].to_sentence # ""
368
- ["test"].to_sentence # "test"
371
+ ["demo"].to_sentence # "demo"
369
372
  ["a", :b].to_sentence # "a and b"
370
- [1, "a", :b, 2.0, /\w+/].map(&:inspect).to_sentence # 1, "a", :b, 2.0, and /\w+/
373
+ [1, "a", :b, 2.0, /\w+/].to_sentence # "1, a, b, 2.0, and (?-mix:\\w+)"
371
374
  %w[one two three].to_sentence # "one, two, and three"
372
375
  %w[eins zwei drei].to_sentence "und", delimiter: " " # "eins zwei und drei"
373
376
  ----
374
377
 
375
378
  ===== #to_usage
376
379
 
377
- Builds upon and enhances `#to_sentence` further by answering a sentence which all elements are inspected -- where each element of the array is called with `#inspect` -- before turned into a sentence using `"and"` as the default conjunction and `", "` as the default delimiter. This is useful when providing detailed error messages _and_ you need to show the element types used.
380
+ Builds upon and enhances `#to_sentence` further by answering a sentence which all elements are inspected -- where each element of the array is called with `#inspect` -- before turned into a sentence using `"and"` as the default conjunction and `", "` as the default delimiter. This is useful when providing detailed error messages _and_ you need to detail the types of element used.
378
381
 
379
382
  [source,ruby]
380
383
  ----
381
384
  [].to_usage # ""
382
- ["test"].to_usage # "test"
383
- ["a", :b].to_usage # "a and b"
384
- [1, "a", :b, 2.0, /\w+/].map(&:inspect).to_usage # 1, "a", :b, 2.0, and /\w+/
385
- %w[one two three].to_usage # "one, two, and three"
386
- %w[eins zwei drei].to_usage "und", delimiter: " " # "eins zwei und drei"
385
+ ["demo"].to_usage # "\"demo\""
386
+ ["a", :b].to_usage # "\"a\" and :b"
387
+ [1, "a", :b, 2.0, /\w+/].to_usage # "1, \"a\", :b, 2.0, and /\\w+/"
388
+ %w[one two three].to_usage # "\"one\", \"two\", and \"three\""
389
+ %w[eins zwei drei].to_usage "und", delimiter: " " # "\"eins\" \"zwei\" und \"drei\""
387
390
  ----
388
391
 
389
392
  ==== Big Decimal
@@ -397,6 +400,28 @@ Allows one to inspect a big decimal with numeric representation.
397
400
  BigDecimal.new("5.0E-10").inspect # "#<BigDecimal:3fd3d458fe84 0.0000000005>"
398
401
  ----
399
402
 
403
+ ==== Data
404
+
405
+ ===== #diff
406
+
407
+ Allows you to obtain the differences between two objects.
408
+
409
+ [source,ruby]
410
+ ----
411
+ implementation = Data.define :a, :b, :c
412
+
413
+ one = implementation.new a: 1, b: 2, c: 3
414
+ two = implementation.new a: 3, b: 2, c: 1
415
+ three = Data.define(:x, :y).new x: 1, y: 2
416
+
417
+ one.diff one # {}
418
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
419
+ one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
420
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
421
+ ----
422
+
423
+ Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
424
+
400
425
  ==== DateTime
401
426
 
402
427
  ===== .utc
@@ -532,6 +557,26 @@ example.deep_symbolize_keys! # {a: {b: 1}}
532
557
  example # {a: {b: 1}}
533
558
  ----
534
559
 
560
+ ===== #diff
561
+
562
+ Allows you to obtain the differences between two objects.
563
+
564
+ [source,ruby]
565
+ ----
566
+ one = {a: 1, b: 2, c: 3}
567
+ two = {a: 3, b: 2, c: 1}
568
+ three = {c: 3, b: 2, a: 1}
569
+ four = Data.define(:x, :y).new x: 1, y: 2
570
+
571
+ one.diff one # {}
572
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
573
+ one.diff three # {}
574
+ one.diff four # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
575
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
576
+ ----
577
+
578
+ 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.
579
+
535
580
  ===== #fetch_value
536
581
 
537
582
  Fetches value for exiting or missing key. Behavior is identical to `#fetch` except when the value of
@@ -540,12 +585,12 @@ expression `example.fetch(:desired_key) || "default_value"`.
540
585
 
541
586
  [source,ruby]
542
587
  ----
543
- {a: "test"}.fetch_value :a, "default" # "test"
544
- {a: "test"}.fetch_value :a # "test"
588
+ {a: "demo"}.fetch_value :a, "default" # "demo"
589
+ {a: "demo"}.fetch_value :a # "demo"
545
590
  {a: nil}.fetch_value :a, "default" # "default"
546
591
  {}.fetch_value(:a) { "default" } # "default"
547
592
  {}.fetch_value :a # KeyError
548
- {a: "test"}.fetch_value # ArgumentError
593
+ {a: "demo"}.fetch_value # ArgumentError
549
594
  ----
550
595
 
551
596
  ===== #flatten_keys
@@ -555,7 +600,7 @@ though.
555
600
 
556
601
  [source,ruby]
557
602
  ----
558
- {a: {b: 1}}.flatten_keys prefix: :test # {test_a_b: 1}
603
+ {a: {b: 1}}.flatten_keys prefix: :demo # {demo_a_b: 1}
559
604
  {a: {b: 1}}.flatten_keys delimiter: :| # {:"a|b" => 1}
560
605
 
561
606
  example = {a: {b: 1}}
@@ -570,7 +615,7 @@ though.
570
615
 
571
616
  [source,ruby]
572
617
  ----
573
- {a: {b: 1}}.flatten_keys! prefix: :test # {test_a_b: 1}
618
+ {a: {b: 1}}.flatten_keys! prefix: :demo # {demo_a_b: 1}
574
619
  {a: {b: 1}}.flatten_keys! delimiter: :| # {:"a|b" => 1}
575
620
 
576
621
  example = {a: {b: 1}}
@@ -735,11 +780,11 @@ answered instead.
735
780
 
736
781
  [source,ruby]
737
782
  ----
738
- io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
783
+ io = IO.new IO.sysopen(Pathname("demo.txt").to_s, "w+")
739
784
  other = IO.new IO.sysopen(Pathname("other.txt").to_s, "w+")
740
785
 
741
786
  io.redirect other # "#<IO:fd 20>"
742
- io.redirect(other) { |stream| stream.write "test" } # "#<IO:fd 21>"
787
+ io.redirect(other) { |stream| stream.write "demo" } # "#<IO:fd 21>"
743
788
  ----
744
789
 
745
790
  ===== #reread
@@ -748,15 +793,15 @@ Answers full stream by rewinding to beginning of stream and reading all content.
748
793
 
749
794
  [source,ruby]
750
795
  ----
751
- io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
752
- io.write "This is a test."
796
+ io = IO.new IO.sysopen(Pathname("demo.txt").to_s, "w+")
797
+ io.write "This is a demo."
753
798
 
754
- io.reread # "This is a test."
799
+ io.reread # "This is a demo."
755
800
  io.reread 4 # "This"
756
801
 
757
802
  buffer = "".dup
758
- io.reread(buffer: buffer) # "This is a test."
759
- buffer # "This is a test."
803
+ io.reread(buffer: buffer) # "This is a demo."
804
+ buffer # "This is a demo."
760
805
  ----
761
806
 
762
807
  ===== #squelch
@@ -1355,6 +1400,26 @@ Example.with_positions 1, 2, 3 # #<struct a=1, b=2, c=3>
1355
1400
  Example.with_positions 1 # #<struct a=1, b=nil, c=nil>
1356
1401
  ----
1357
1402
 
1403
+ ===== #diff
1404
+
1405
+ Allows you to obtain the differences between two objects.
1406
+
1407
+ [source,ruby]
1408
+ ----
1409
+ implementation = Struct.new :a, :b, :c
1410
+
1411
+ one = implementation.new a: 1, b: 2, c: 3
1412
+ two = implementation.new a: 3, b: 2, c: 1
1413
+ three = Struct.new(:x, :y).new x: 1, y: 2
1414
+
1415
+ one.diff one # {}
1416
+ one.diff two # {:a=>[1, 3], :c=>[3, 1]}
1417
+ one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
1418
+ one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
1419
+ ----
1420
+
1421
+ Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
1422
+
1358
1423
  ===== #merge
1359
1424
 
1360
1425
  Merges multiple attributes without mutating itself and supports any object that responds to `#to_h`.
@@ -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,6 +45,12 @@ module Refinements
45
45
 
46
46
  def deep_symbolize_keys! = replace(deep_symbolize_keys)
47
47
 
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
+
48
54
  def fetch_value(key, *default_value, &) = fetch(key, *default_value, &) || default_value.first
49
55
 
50
56
  def flatten_keys prefix: nil, delimiter: "_"
@@ -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.0"
5
+ spec.version = "11.1.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: 11.0.0
4
+ version: 11.1.0
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-13 00:00:00.000000000 Z
38
+ date: 2023-08-15 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.18
94
96
  signing_key:
95
97
  specification_version: 4
96
98
  summary: A collection of core Ruby object refinements.
metadata.gz.sig CHANGED
Binary file