refinements 7.14.0 → 7.18.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: 4abbbd79616d97836ca58503bb4638e2638e14732e76e7c00b3f5c033f708edc
4
- data.tar.gz: 516c79b5361a7512ca4e63c72303d8fb0d2cb85c693bc9aa13c36ef767580f10
3
+ metadata.gz: 5dd9bd6cbc9800c0c66d8c1ae4ed93124143f196a4173723438bb7d9fc12957e
4
+ data.tar.gz: 9d6651c258900528aa68db2a8b26e1bd77aef9be70fe3fbeadf63e4c0580ab45
5
5
  SHA512:
6
- metadata.gz: 2f15aa4b466d6e610a2ffc45ad16285d27107c93a4260d214abcee42e66005951a5f2a708da6b04a28826ab3abd0a85ad0e1a707782b6ba5c51ef5cb0b705ec7
7
- data.tar.gz: ec214191217bb870ca264fbfe3fa31d57b6c37c28e0f92806f779d3ea8400fbac11ee4aa38c82d6d10d7b07187a2360a7aa810ef802e6d219a217043cd76e69c
6
+ metadata.gz: bad8de30ca4c07607013a08d8346d1390b3f6223b943588ac94ce1c7e44fb5f59ebb634c9adb4d0f1773929ede430ffc7025fa9e6fcdca6f055d3bfa4c5cbeb8
7
+ data.tar.gz: d81030c3b1a8db17fff6cafea12496041d2cb95e87452cf932c7cf03c60dea4971f1bbce59c30fde5b5a8d80f713b5a00fca1cbcbba6bbb1962f77e21984f9b0
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -28,6 +28,7 @@ Enhances the following objects:
28
28
  * Pathname
29
29
  * String
30
30
  * StringIO
31
+ * Structs
31
32
 
32
33
  == Requirements
33
34
 
@@ -75,6 +76,7 @@ require "refinements/ios"
75
76
  require "refinements/pathnames"
76
77
  require "refinements/strings"
77
78
  require "refinements/string_ios"
79
+ require "refinements/structs"
78
80
  ----
79
81
 
80
82
  === Using
@@ -94,6 +96,7 @@ class Example
94
96
  using Refinements::Pathnames
95
97
  using Refinements::Strings
96
98
  using Refinements::StringIOs
99
+ using Refinements::Structs
97
100
  end
98
101
  ----
99
102
 
@@ -168,6 +171,18 @@ Answers mean/average all elements within an array.
168
171
  [1.25, 1.5, 1.75].mean # => 1.5
169
172
  ----
170
173
 
174
+ ===== #pad
175
+
176
+ Answers new array padded with given value up to a maximum size. Useful in situations where an array
177
+ needs to be a specific size with padded values.
178
+
179
+ [source,ruby]
180
+ ----
181
+ [1].pad 0 # => [1]
182
+ [1].pad 0, max: 3 # => [1, 0, 0]
183
+ [1, 2].pad 3, max: 3 # => [1, 2, 3]
184
+ ----
185
+
171
186
  ===== #ring
172
187
 
173
188
  Answers a circular array which can enumerate before, current, after elements.
@@ -237,10 +252,10 @@ Answers new hash where every top-level missing key has the same default value.
237
252
  [source,ruby]
238
253
  ----
239
254
  example = Hash.with_default ""
240
- example[:a] # => ""
255
+ example[:a] # => ""
241
256
 
242
257
  example = Hash.with_default []
243
- example[:b] # => []
258
+ example[:b] # => []
244
259
  ----
245
260
 
246
261
  ===== #deep_merge
@@ -468,7 +483,7 @@ Passes each hash value as a block argument for further processing.
468
483
  [source,ruby]
469
484
  ----
470
485
  example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
471
- example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
486
+ example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
472
487
  ----
473
488
 
474
489
  ==== IO
@@ -481,11 +496,8 @@ block, you'll need to close the stream manually.
481
496
 
482
497
  [source,ruby]
483
498
  ----
484
- io = IO.void
485
- io.closed? # => false
486
-
487
- io = IO.void { |void| void.write "nevermore" }
488
- io.closed? # => true
499
+ io = IO.void # => #<IO:fd 20>
500
+ io = IO.void { |void| void.write "nevermore" } # => #<IO:(closed)>
489
501
  ----
490
502
 
491
503
  ===== #redirect
@@ -498,11 +510,8 @@ answered instead.
498
510
  io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
499
511
  other = IO.new IO.sysopen(Pathname("other.txt").to_s, "w+")
500
512
 
501
- io.redirect other # => `io`
502
-
503
- io.redirect(other) { |stream| stream.write "test" }
504
- .close # => ""
505
- other.close # => "test"
513
+ io.redirect other # => #<IO:fd 20>
514
+ io.redirect(other) { |stream| stream.write "test" } # => #<IO:fd 21>
506
515
  ----
507
516
 
508
517
  ===== #reread
@@ -518,40 +527,110 @@ io.reread # => "This is a test."
518
527
  io.reread 4 # => "This"
519
528
 
520
529
  buffer = "".dup
521
- io.reread(buffer: buffer)
522
- buffer # => "This is a test."
530
+ io.reread(buffer: buffer) # => "This is a test."
531
+ buffer # => "This is a test."
523
532
  ----
524
533
 
525
534
  ===== #squelch
526
535
 
527
- Temporarily ignores any reads/writes for current stream for all code executed within the block. When
528
- not given a block, it answers itself.
536
+ Temporarily ignores any reads/writes for code executed within a block. Answers itself without any
537
+ arguments or when given a block.
529
538
 
530
539
  [source,ruby]
531
540
  ----
532
541
  io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
533
- io.squelch { io.write "Test" }
534
- io.reread # => ""
542
+ io.squelch # => #<IO:fd 20>
543
+ io.squelch { io.write "Test" } # => #<IO:fd 20>
544
+ io.reread # => ""
535
545
  ----
536
546
 
537
547
  ==== Pathname
538
548
 
539
549
  ===== Pathname
540
550
 
541
- Enhances the conversion function -- refined from `Kernel` -- which casts `nil` into a pathname in
542
- order to avoid: `TypeError (no implicit conversion of nil into String)`. The pathname is still
543
- invalid but at least you have an instance of `Pathname`, which behaves like a _Null Object_, that
544
- can still be used to construct a valid path.
551
+ Enhances the `Kernel` conversion function which casts `nil` into a pathname in order to avoid:
552
+ `TypeError (no implicit conversion of nil into String)`. The pathname remains invalid but at least
553
+ you have an instance of `Pathname`, which behaves like a _Null Object_, that can be used to
554
+ construct a valid path.
545
555
 
546
556
  [source,ruby]
547
557
  ----
548
558
  Pathname(nil) # => Pathname("")
549
559
  ----
550
560
 
561
+ ===== .home
562
+
563
+ Answers user home directory.
564
+
565
+ [source,ruby]
566
+ ----
567
+ Pathname.home # => Pathname "/Users/bkuhlmann"
568
+ ----
569
+
570
+ ===== .make_temp_dir
571
+
572
+ Wraps `Dir.mktmpdir` with the following behavior (see
573
+ link:https://rubyapi.org/o/Dir.mktmpdir#method-c-mktmpdir[Dir.mktmpdir] for details):
574
+
575
+ * *Without Block* - Answers a newly created Pathname instance which is not automatically cleaned up.
576
+ * *With Block* Yields a Pathname instance, answers result of given block, and automatidally cleans
577
+ up temporary directory after block exits.
578
+
579
+ The following examples use truncated temporary directories for illustration purposes only. In
580
+ reality, these paths will be longer depending on which operating system you are using.
581
+
582
+ [source,ruby]
583
+ ----
584
+ Pathname.make_temp_dir # => Pathname:/var/folders/T/temp-20200101-16940-r8
585
+ Pathname.make_temp_dir prefix: "prefix-" # => Pathname:/var/folders/T/prefix-20200101-16940-r8
586
+ Pathname.make_temp_dir suffix: "-suffix" # => Pathname:/var/folders/T/temp-20200101-16940-r8-suffix
587
+ Pathname.make_temp_dir prefix: "prefix-", suffix: "-suffix" # => Pathname:/var/folders/T/prefix-20200101-16940-r8-suffix
588
+ Pathname.make_temp_dir root: "/example" # => Pathname:/example/temp-20200101-16940-r8
589
+ Pathname.make_temp_dir { "I am a block result" } # => "I am a block result"
590
+ Pathname.make_temp_dir { |path| path.join "sub_dir" } # => Pathname:/var/folders/T/temp-20200101-16940-r8/sub_dir
591
+ ----
592
+
593
+ ===== .require_tree
594
+
595
+ Requires all files in given root path and corresponding nested tree structure. All files are sorted
596
+ before being required to ensure consistent behavior. Example:
597
+
598
+ [source,ruby]
599
+ ----
600
+ # Before
601
+ Dir[File.join(__dir__, "support/shared_contexts/**/*.rb")].sort.each { |path| require path }
602
+
603
+ # After
604
+ Pathname.require_tree __dir__, "support/shared_contexts/**/*.rb"
605
+ ----
606
+
607
+ The following are further examples of potential usage:
608
+
609
+ [source,ruby]
610
+ ----
611
+ # Requires all files in root directory and below.
612
+ Pathname.require_tree __dir__
613
+
614
+ # Requires all files in `/test/**/*.rb` and below.
615
+ Pathname.require_tree "/test"
616
+
617
+ # Requires all files in RSpec shared examples directory structure.
618
+ Pathname.require_tree Bundler.root.join("spec"), "support/shared_examples/**/*.rb"
619
+ ----
620
+
621
+ ===== .root
622
+
623
+ Answers operating system root path.
624
+
625
+ [source,ruby]
626
+ ----
627
+ Pathname.root # => Pathname "/"
628
+ ----
629
+
551
630
  ===== #change_dir
552
631
 
553
- Inherits and wraps `Dir.chdir` behavior by changing to directory of current path. See
554
- link:https://rubyapi.org/2.7/o/s?q=Dir.chdir[Dir.chdir] for details.
632
+ Wraps `Dir.chdir` behavior by changing to directory of current path. See
633
+ link:https://rubyapi.org/o/Dir.chdir#method-c-chdir[Dir.chdir] for details.
555
634
 
556
635
  [source,ruby]
557
636
  ----
@@ -559,23 +638,23 @@ Pathname.pwd # => "/"
559
638
  Pathname("/test").make_dir.change_dir # => Pathname "/test"
560
639
  Pathname.pwd # => "/test"
561
640
 
562
- Pathname.pwd # => "/"
563
- Pathname("/test").make_dir.change_dir { # Implementation details } # => Pathname "/test"
564
- Pathname.pwd # => "/"
641
+ Pathname.pwd # => "/"
642
+ Pathname("/test").make_dir.change_dir { "example" } # => "example"
643
+ Pathname.pwd # => "/"
565
644
  ----
566
645
 
567
646
  ===== #copy
568
647
 
569
- Copies file from current location to new location.
648
+ Copies file from current location to new location while answering itself so it can be chained.
570
649
 
571
650
  [source,ruby]
572
651
  ----
573
- Pathname("input.txt").copy Pathname("output.txt")
652
+ Pathname("input.txt").copy Pathname("output.txt") # => Pathname("input.txt")
574
653
  ----
575
654
 
576
655
  ===== #directories
577
656
 
578
- Answers all or filtered directories for current path.
657
+ Answers all directories or filtered directories for current path.
579
658
 
580
659
  [source,ruby]
581
660
  ----
@@ -590,12 +669,12 @@ Answers file extensions as an array.
590
669
 
591
670
  [source,ruby]
592
671
  ----
593
- Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
672
+ Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
594
673
  ----
595
674
 
596
675
  ===== #files
597
676
 
598
- Answers all or filtered files for current path.
677
+ Answers all files or filtered files for current path.
599
678
 
600
679
  [source,ruby]
601
680
  ----
@@ -623,9 +702,9 @@ Ensures all ancestor directories are created for a path.
623
702
 
624
703
  [source,ruby]
625
704
  ----
626
- Pathname("/one/two").make_ancestors
627
- Pathname("/one").exist? # => true
628
- Pathname("/one/two").exist? # => false
705
+ Pathname("/one/two").make_ancestors # => Pathname("/one/two")
706
+ Pathname("/one").exist? # => true
707
+ Pathname("/one/two").exist? # => false
629
708
  ----
630
709
 
631
710
  ===== #make_dir
@@ -708,7 +787,8 @@ immediate writing back to the same file.
708
787
 
709
788
  [source,ruby]
710
789
  ----
711
- Pathname("/test.txt").rewrite { |content| content.sub "[placeholder]", "example" }
790
+ Pathname("/test.txt").rewrite # => Pathname("/test.txt")
791
+ Pathname("/test.txt").rewrite { |body| body.sub "[token]", "example" } # => Pathname("/test.txt")
712
792
  ----
713
793
 
714
794
  ===== #touch
@@ -717,8 +797,20 @@ Updates access and modification times for path. Defaults to current time.
717
797
 
718
798
  [source,ruby]
719
799
  ----
720
- Pathname("example.txt").touch
721
- Pathname("example.txt").touch at: Time.now - 1
800
+ Pathname("example.txt").touch # => Pathname("example.txt")
801
+ Pathname("example.txt").touch at: Time.now - 1 # => Pathname("example.txt")
802
+ ----
803
+
804
+ ===== #write
805
+
806
+ Writes to file and answers itself so it can be chained. See `IO.write` for details on additional
807
+ options.
808
+
809
+ [source,ruby]
810
+ ----
811
+ Pathname("example.txt").write "test" # => Pathname("example.txt")
812
+ Pathname("example.txt").write "test", offset: 1 # => Pathname("example.txt")
813
+ Pathname("example.txt").write "test", mode: "a" # => Pathname("example.txt")
722
814
  ----
723
815
 
724
816
  ==== String
@@ -838,8 +930,143 @@ io.reread # => "This is a test."
838
930
  io.reread 4 # => "This"
839
931
 
840
932
  buffer = "".dup
841
- io.reread(buffer: buffer)
842
- buffer # => "This is a test."
933
+ io.reread(buffer: buffer) # => "This is a test."
934
+ buffer # => "This is a test."
935
+ ----
936
+
937
+ ==== Struct
938
+
939
+ ===== .keyworded?
940
+
941
+ Answers whether a struct was constructed with keyword or positional arguments.
942
+
943
+ [source,ruby]
944
+ ----
945
+ Struct.new(:a, keyword_init: true).keyworded? # => true
946
+ Struct.new(:a).keyworded? # => false
947
+ ----
948
+
949
+ ===== .with_keywords
950
+
951
+ Answers a struct instance with given keyword arguments regardless of
952
+ whether the struct was constructed with positional or keyword arguments.
953
+
954
+ [source,ruby]
955
+ ----
956
+ Example = Struct.new :a, :b, :c
957
+ Example.with_keywords a: 1, b: 2, c: 3 # => #<struct a=1, b=2, c=3>
958
+ Example.with_keywords a: 1 # => #<struct a=1, b=nil, c=nil>
959
+ Example.with_keywords c: 1 # => #<struct a=nil, b=nil, c=1>
960
+
961
+ Example = Struct.new :a, :b, :c, keyword_init: true
962
+ Example.with_keywords a: 1, b: 2, c: 3 # => #<struct a=1, b=2, c=3>
963
+ Example.with_keywords a: 1 # => #<struct a=1, b=nil, c=nil>
964
+ Example.with_keywords c: 1 # => #<struct a=nil, b=nil, c=1>
965
+ ----
966
+
967
+ ===== .with_positions
968
+
969
+ Answers a struct instance with given positional arguments regardless of
970
+ whether the struct was constructed with positional or keyword arguments.
971
+
972
+ [source,ruby]
973
+ ----
974
+ Example = Struct.new :a, :b, :c
975
+ Example.with_positions 1, 2, 3 # => #<struct a=1, b=2, c=3>
976
+ Example.with_positions 1 # => #<struct a=1, b=nil, c=nil>
977
+
978
+ Example = Struct.new :a, :b, :c, keyword_init: true
979
+ Example.with_positions 1, 2, 3 # => #<struct a=1, b=2, c=3>
980
+ Example.with_positions 1 # => #<struct a=1, b=nil, c=nil>
981
+ ----
982
+
983
+ ===== #merge
984
+
985
+ Merges multiple attributes without mutating itself.
986
+
987
+ [source,ruby]
988
+ ----
989
+ Example = Struct.new :a, :b, :c
990
+ example = Example[1, 2, 3]
991
+ example.merge a: 10 # => #<struct a=10, b=2, c=3>
992
+ example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
993
+ example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
994
+ example # => #<struct a=1, b=2, c=3>
995
+
996
+ Example = Struct.new :a, :b, :c, keyword_init: true
997
+ example = Example[a: 1, b: 2, c: 3]
998
+ example.merge a: 10 # => #<struct a=10, b=2, c=3>
999
+ example.merge a: 10, c: 30 # => #<struct a=10, b=2, c=30>
1000
+ example.merge a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
1001
+ example # => #<struct a=1, b=2, c=3>
1002
+ ----
1003
+
1004
+ ===== #merge!
1005
+
1006
+ Merges multiple attributes while mutating itself.
1007
+
1008
+ [source,ruby]
1009
+ ----
1010
+ Example = Struct.new :a, :b, :c
1011
+ example = Example[1, 2, 3]
1012
+ example.merge! a: 10 # => #<struct a=10, b=2, c=3>
1013
+ example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
1014
+ example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
1015
+ example # => #<struct a=10, b=20, c=30>
1016
+
1017
+ Example = Struct.new :a, :b, :c, keyword_init: true
1018
+ example = Example[a: 1, b: 2, c: 3]
1019
+ example.merge! a: 10 # => #<struct a=10, b=2, c=3>
1020
+ example.merge! a: 10, c: 30 # => #<struct a=10, b=2, c=30>
1021
+ example.merge! a: 10, b: 20, c: 30 # => #<struct a=10, b=20, c=30>
1022
+ example # => #<struct a=10, b=20, c=30>
1023
+ ----
1024
+
1025
+ ===== #revalue
1026
+
1027
+ Transforms values without mutating itself. An optional hash can be supplied to pinpoint and
1028
+ transform specific attributes. In the event that a block isn't supplied, the struct will answer
1029
+ itself since there is nothing to operate on. Behavior is the same regardless of whether the struct
1030
+ is constructed using positional or keyword arguments. A positional struct is used in the examples
1031
+ below but a keyword struct would work too.
1032
+
1033
+ [source,ruby]
1034
+ ----
1035
+ Example = Struct.new :a, :b, :c
1036
+
1037
+ example = Example[1, 2, 3]
1038
+ example.revalue { |value| value * 2 } # => #<struct a=2, b=4, c=6>
1039
+ example.revalue(c: 2) { |previous, current| previous + current } # => #<struct a=1, b=2, c=5>
1040
+ example.revalue c: 2 # => #<struct a=1, b=2, c=3>
1041
+ example.revalue # => #<struct a=1, b=2, c=3>
1042
+ example # => #<struct a=1, b=2, c=3>
1043
+
1044
+ ----
1045
+
1046
+ ===== #revalue!
1047
+
1048
+ Transforms values while mutating itself. An optional hash can be supplied to pinpoint and transform
1049
+ specific attributes. In the event that a block isn't supplied, the struct will answer itself since
1050
+ there is nothing to operate on. Behavior is the same regardless of whether the struct is constructed
1051
+ using positional or keyword arguments. A positional struct is used in the examples below but a
1052
+ keyword struct would work too.
1053
+
1054
+ [source,ruby]
1055
+ ----
1056
+ Example = Struct.new :a, :b, :c
1057
+
1058
+ example = Example[1, 2, 3]
1059
+ example.revalue! { |value| value * 2 } # => #<struct a=2, b=4, c=6>
1060
+ example # => #<struct a=2, b=4, c=6>
1061
+
1062
+ example = Example[1, 2, 3]
1063
+ example.revalue!(c: 2) { |previous, current| previous + current } # => #<struct a=1, b=2, c=5>
1064
+ example # => #<struct a=1, b=2, c=5>
1065
+
1066
+ example = Example[1, 2, 3]
1067
+ example.revalue! c: 2 # => #<struct a=1, b=2, c=3>
1068
+ example.revalue! # => #<struct a=1, b=2, c=3>
1069
+ example # => #<struct a=1, b=2, c=3>
843
1070
  ----
844
1071
 
845
1072
  == Development
@@ -10,3 +10,4 @@ require "refinements/ios"
10
10
  require "refinements/pathnames"
11
11
  require "refinements/strings"
12
12
  require "refinements/string_ios"
13
+ require "refinements/structs"
@@ -37,6 +37,10 @@ module Refinements
37
37
  size.zero? ? 0 : sum(0) / size
38
38
  end
39
39
 
40
+ def pad value, max: size
41
+ dup.fill value, size..(max - 1)
42
+ end
43
+
40
44
  def ring &block
41
45
  [last, *self, first].each_cons 3, &block
42
46
  end
@@ -73,7 +73,7 @@ module Refinements
73
73
  end
74
74
 
75
75
  def recurse &block
76
- return self unless block_given?
76
+ return self unless block
77
77
 
78
78
  transform = yield self
79
79
 
@@ -119,7 +119,7 @@ module Refinements
119
119
  end
120
120
 
121
121
  def use &block
122
- return [] unless block_given?
122
+ return [] unless block
123
123
 
124
124
  block.parameters
125
125
  .map { |(_type, key)| self[key] }
@@ -5,7 +5,7 @@ module Refinements
5
5
  module Identity
6
6
  NAME = "refinements"
7
7
  LABEL = "Refinements"
8
- VERSION = "7.14.0"
8
+ VERSION = "7.18.0"
9
9
  VERSION_LABEL = "#{LABEL} #{VERSION}"
10
10
  end
11
11
  end
@@ -12,9 +12,27 @@ module Refinements
12
12
  end
13
13
  end
14
14
 
15
+ refine Pathname.singleton_class do
16
+ def home
17
+ new ENV["HOME"]
18
+ end
19
+
20
+ def make_temp_dir prefix: "temp-", suffix: nil, root: nil
21
+ Dir.mktmpdir([prefix, suffix], root) { |path| block_given? ? yield(new path) : new(path) }
22
+ end
23
+
24
+ def require_tree root, pattern = "**/*.rb"
25
+ new(root).files(pattern).each { |path| require path.to_s }
26
+ end
27
+
28
+ def root
29
+ new "/"
30
+ end
31
+ end
32
+
15
33
  refine Pathname do
16
34
  def change_dir &block
17
- block_given? ? Dir.chdir(self, &block) : (Dir.chdir self and self)
35
+ block ? Dir.chdir(self, &block) : (Dir.chdir self and self)
18
36
  end
19
37
 
20
38
  def copy to
@@ -82,13 +100,17 @@ module Refinements
82
100
 
83
101
  def rewrite
84
102
  read.then { |content| write yield(content) if block_given? }
85
- self
86
103
  end
87
104
 
88
105
  def touch at: Time.now
89
106
  exist? ? utime(at, at) : write("")
90
107
  self
91
108
  end
109
+
110
+ def write content, offset: nil, **options
111
+ super content, offset, **options
112
+ self
113
+ end
92
114
  end
93
115
  end
94
116
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Refinements
4
+ module Structs
5
+ refine Struct.singleton_class do
6
+ def keyworded?
7
+ inspect.include? "keyword_init: true"
8
+ end
9
+
10
+ def with_keywords arguments
11
+ keyworded? ? new(arguments) : new.merge!(arguments)
12
+ end
13
+
14
+ def with_positions *values
15
+ keyworded? ? new(Hash[members.zip values]) : new(*values)
16
+ end
17
+ end
18
+
19
+ refine Struct do
20
+ def merge **attributes
21
+ dup.merge! attributes
22
+ end
23
+
24
+ def merge! **attributes
25
+ to_h.merge(attributes).each { |key, value| self[key] = value }
26
+ self
27
+ end
28
+
29
+ def revalue attributes = each_pair
30
+ return self unless block_given?
31
+
32
+ dup.tap do |copy|
33
+ attributes.each { |key, value| copy[key] = yield self[key], value }
34
+ end
35
+ end
36
+
37
+ def revalue! attributes = each_pair
38
+ return self unless block_given?
39
+
40
+ attributes.each { |key, value| self[key] = yield self[key], value }
41
+ self
42
+ end
43
+ end
44
+ end
45
+ end
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: 7.14.0
4
+ version: 7.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,190 +28,8 @@ cert_chain:
28
28
  2XV8FRa7/JimI07sPLC13eLY3xd/aYTi85Z782KIA4j0G8XEEWAX0ouBhlXPocZv
29
29
  QWc=
30
30
  -----END CERTIFICATE-----
31
- date: 2020-11-14 00:00:00.000000000 Z
32
- dependencies:
33
- - !ruby/object:Gem::Dependency
34
- name: bundler-audit
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '0.7'
40
- type: :development
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '0.7'
47
- - !ruby/object:Gem::Dependency
48
- name: bundler-leak
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '0.2'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '0.2'
61
- - !ruby/object:Gem::Dependency
62
- name: guard-rspec
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '4.7'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '4.7'
75
- - !ruby/object:Gem::Dependency
76
- name: pry
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.13'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.13'
89
- - !ruby/object:Gem::Dependency
90
- name: pry-byebug
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '3.9'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '3.9'
103
- - !ruby/object:Gem::Dependency
104
- name: rake
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '13.0'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: '13.0'
117
- - !ruby/object:Gem::Dependency
118
- name: reek
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '6.0'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '6.0'
131
- - !ruby/object:Gem::Dependency
132
- name: rspec
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '3.10'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '3.10'
145
- - !ruby/object:Gem::Dependency
146
- name: rubocop
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '1.3'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '1.3'
159
- - !ruby/object:Gem::Dependency
160
- name: rubocop-performance
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '1.8'
166
- type: :development
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - "~>"
171
- - !ruby/object:Gem::Version
172
- version: '1.8'
173
- - !ruby/object:Gem::Dependency
174
- name: rubocop-rake
175
- requirement: !ruby/object:Gem::Requirement
176
- requirements:
177
- - - "~>"
178
- - !ruby/object:Gem::Version
179
- version: '0.5'
180
- type: :development
181
- prerelease: false
182
- version_requirements: !ruby/object:Gem::Requirement
183
- requirements:
184
- - - "~>"
185
- - !ruby/object:Gem::Version
186
- version: '0.5'
187
- - !ruby/object:Gem::Dependency
188
- name: rubocop-rspec
189
- requirement: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - "~>"
192
- - !ruby/object:Gem::Version
193
- version: '2.0'
194
- type: :development
195
- prerelease: false
196
- version_requirements: !ruby/object:Gem::Requirement
197
- requirements:
198
- - - "~>"
199
- - !ruby/object:Gem::Version
200
- version: '2.0'
201
- - !ruby/object:Gem::Dependency
202
- name: simplecov
203
- requirement: !ruby/object:Gem::Requirement
204
- requirements:
205
- - - "~>"
206
- - !ruby/object:Gem::Version
207
- version: '0.19'
208
- type: :development
209
- prerelease: false
210
- version_requirements: !ruby/object:Gem::Requirement
211
- requirements:
212
- - - "~>"
213
- - !ruby/object:Gem::Version
214
- version: '0.19'
31
+ date: 2020-12-21 00:00:00.000000000 Z
32
+ dependencies: []
215
33
  description:
216
34
  email:
217
35
  - brooke@alchemists.io
@@ -234,6 +52,7 @@ files:
234
52
  - lib/refinements/pathnames.rb
235
53
  - lib/refinements/string_ios.rb
236
54
  - lib/refinements/strings.rb
55
+ - lib/refinements/structs.rb
237
56
  homepage: https://www.alchemists.io/projects/refinements
238
57
  licenses:
239
58
  - Apache-2.0
@@ -257,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
76
  - !ruby/object:Gem::Version
258
77
  version: '0'
259
78
  requirements: []
260
- rubygems_version: 3.1.4
79
+ rubygems_version: 3.2.2
261
80
  signing_key:
262
81
  specification_version: 4
263
82
  summary: A collection of refinements to core Ruby objects.
metadata.gz.sig CHANGED
Binary file