rekey 4.1.0 → 4.2.0

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: fa46e960e7f7282b323629b69f26868f9eb59f09752128afc01858fcd33e74b2
4
- data.tar.gz: 6bdf503d29bdfce9e99a43a0ad6b418c1d3905b5c512a318e0b7bcab2f60b48d
3
+ metadata.gz: 2fa7a26ea0c5de294ea7b5b87c72d9bfb1dfe60bd4aed34068712d0e751dab4d
4
+ data.tar.gz: d4021c41d1147df578cb411224c53adcef870b1484e45c432c83f9312b81a089
5
5
  SHA512:
6
- metadata.gz: dac8e9d6262d58ab957ca9175cbc081314612519776737cacce78f89580c65e0aa72393e6d79a0f43a230fa0dbde16b470a5292efabc98e55dd8156362d4f5b8
7
- data.tar.gz: 01ed776768fed346f854f3ece0a4af3cf1a2cede9c13d390f5528a2af51f8e89b2125005b15fff65ccda8f5a5dc926b5a2c17c75908b87918f77cdd5fd293201
6
+ metadata.gz: af81ef145ff59e27ac19c720f44f4976c69df570c2d19d7b711f134906df651c8e202798ab9429644b59dba4e4f47d0cd367db90a07b8838a4540d522cfd8a19
7
+ data.tar.gz: '0986dbde9b4e19dcc4f4b07ce619396a335b990258107ce0b5314844aa0a2e5d24fe4fd3d43379e9fb7af2fd619a38d6587a8baf708cd4db2ecbcdd3d56a6d52'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 4.2.0 (2026-11-03)
2
+ - drop Ruby 3.0 and 3.1 (end of life); requires Ruby >= 3.2
3
+ - fix: a block with two required args and a splat (`|k, v, *rest|`) gets the key and value instead of the value as `k`
4
+ - fix: a `false` handle passed together with a block raises ArgumentError instead of being ignored
5
+ - feature: a callable (lambda, proc, Method) works as a key or value handle: `users.rekey(:id, ->(u) { u.name.upcase })`. Requires pluckit >= 1.3
6
+
1
7
  ### 4.1.0 (2026-04-10)
2
8
  - ruby version / gem updates
3
9
 
data/README.md CHANGED
@@ -3,49 +3,115 @@ Rekey
3
3
  ![Gem](https://img.shields.io/gem/dt/rekey?style=plastic)
4
4
  [![codecov](https://codecov.io/gh/dpep/rekey_rb/branch/main/graph/badge.svg?token=Z6W48XUEQD)](https://codecov.io/gh/dpep/rekey_rb)
5
5
 
6
- Reformat Enumerables into Hashes, using derived keys / values
6
+ Turn an Enumerable into a Hash, with derived keys and values.
7
+
8
+ ```ruby
9
+ require "rekey"
10
+
11
+ rows = [
12
+ { id: 1, name: "alice" },
13
+ { id: 2, name: "bob" },
14
+ ]
15
+
16
+ rows.rekey(:id)
17
+ # => {1 => {id: 1, name: "alice"}, 2 => {id: 2, name: "bob"}}
18
+
19
+ rows.rekey(:id, :name)
20
+ # => {1 => "alice", 2 => "bob"}
21
+ ```
7
22
 
8
23
  #### Install
9
24
  ```gem install rekey```
10
25
 
11
26
 
12
- #### Usage
27
+ #### Handles
28
+ `rekey(key_handle, value_handle = nil)`. Without a value handle, each element is its own value.
29
+
30
+ [pluckit](https://github.com/dpep/pluckit_rb) resolves handles, so a handle can be a Hash key, a method name, an array index, a Range, or a Regexp:
31
+
13
32
  ```ruby
14
- require "rekey"
33
+ [[1, "a"], [2, "b"]].rekey(0, 1)
34
+ # => {1 => "a", 2 => "b"}
15
35
 
16
- # key a list of records by id
17
- [
18
- { id: 1, name: "alice", age: 30},
19
- { id: 2, name: "bob", age: 24},
20
- { id: 3, name: "charlie", age: 88},
21
- ].rekey :id
22
- => {
23
- 1 => { id: 1, name: "alice", age: 30},
24
- 2 => { id: 2, name: "bob", age: 24},
25
- 3 => { id: 3, name: "charlie", age: 88},
26
- }
36
+ %w[apple banana].rekey(0..2, :length)
37
+ # => {"app" => 5, "ban" => 6}
38
+
39
+ %w[apple banana].rekey(/^./)
40
+ # => {"a" => "apple", "b" => "banana"}
41
+ ```
27
42
 
43
+ A callable (lambda, proc, Method) works as either handle:
44
+
45
+ ```ruby
46
+ rows.rekey(:id, ->(r) { r[:name].upcase })
47
+ # => {1 => "ALICE", 2 => "BOB"}
48
+
49
+ [1, 2].rekey(:itself, 10.method(:*))
50
+ # => {1 => 10, 2 => 20}
51
+ ```
52
+
53
+
54
+ #### Blocks
55
+ A block computes the key; the element stays the value.
56
+
57
+ ```ruby
58
+ [2, 4, 6].rekey { |v| v / 2 }
59
+ # => {1 => 2, 2 => 4, 3 => 6}
60
+ ```
61
+
62
+ Pass handles or a block, not both. Mixing them raises ArgumentError.
28
63
 
29
- # create an id => value map from a list of records
30
- [
31
- { id: 1, name: "alice", age: 30},
32
- { id: 2, name: "bob", age: 24},
33
- { id: 3, name: "charlie", age: 88},
34
- ].rekey :id, :name
35
- => {
36
- 1 => "alice",
37
- 2 => "bob",
38
- 3 => "charlie"
39
- }
40
64
 
65
+ #### Hash input
66
+ Handles and one-parameter blocks look at the values. The outer keys are dropped.
41
67
 
42
- # or use blocks
43
- [ 2, 4, 6 ].rekey {|v| v / 2}
44
- => {
45
- 1 => 2,
46
- 2 => 4,
47
- 3 => 6
68
+ ```ruby
69
+ users = {
70
+ x: { id: 1, name: "alice" },
71
+ y: { id: 2, name: "bob" },
48
72
  }
73
+
74
+ users.rekey(:id, :name)
75
+ # => {1 => "alice", 2 => "bob"}
76
+ ```
77
+
78
+ A block with two required parameters gets the key and value:
79
+
80
+ ```ruby
81
+ { a: 1 }.rekey { |k, v| "#{k}#{v}" }
82
+ # => {"a1" => 1}
83
+ ```
84
+
85
+ On anything other than a Hash, a two-parameter block raises ArgumentError.
86
+
87
+
88
+ #### Duplicate keys
89
+ The last one wins, as with `to_h` and `index_by`.
90
+
91
+ ```ruby
92
+ [{ id: 1, v: "a" }, { id: 1, v: "b" }].rekey(:id, :v)
93
+ # => {1 => "b"}
94
+ ```
95
+
96
+ Watch for a handle that misses. A typo, or `"id"` on symbol-keyed hashes, gives `nil` for every row, so the whole result collapses to one entry:
97
+
98
+ ```ruby
99
+ rows.rekey("id")
100
+ # => {nil => {id: 2, name: "bob"}}
101
+ ```
102
+
103
+
104
+ #### Without the monkey patch
105
+ `require "rekey"` adds `#rekey` to every Enumerable. To skip the global patch, load the module alone and use the refinement, or call it directly:
106
+
107
+ ```ruby
108
+ require "rekey/rekey"
109
+
110
+ using Rekey
111
+ rows.rekey(:id)
112
+
113
+ # or
114
+ Rekey.rekey(rows, :id)
49
115
  ```
50
116
 
51
117
 
data/lib/rekey/rekey.rb CHANGED
@@ -27,9 +27,8 @@ module Rekey
27
27
  new_value = value
28
28
 
29
29
  if block
30
- if block.arity < 2
30
+ if required_args(block) < 2
31
31
  # block only wants value
32
- # arity -1 is a function pointer, eg. &:to_i
33
32
  new_key = block.call(value)
34
33
  else
35
34
  # block wants both key and value
@@ -55,9 +54,14 @@ module Rekey
55
54
 
56
55
  private
57
56
 
57
+ # a negative arity means -(required + 1): optional args or a splat follow
58
+ def required_args(block)
59
+ block.arity < 0 ? -block.arity - 1 : block.arity
60
+ end
61
+
58
62
  def validate_input!(key_handle, value_handle, &block)
59
63
  if block
60
- if (key_handle || value_handle)
64
+ unless key_handle.nil? && value_handle.nil?
61
65
  raise ArgumentError, "expected key / value handles, *or* block"
62
66
  end
63
67
  elsif key_handle.nil?
data/lib/rekey/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rekey
2
- VERSION = "4.1.0"
2
+ VERSION = "4.2.0"
3
3
  end
data/rekey.gemspec CHANGED
@@ -1,21 +1,24 @@
1
- package_name = File.basename(__FILE__).split(".")[0]
2
- require "./lib/#{package_name}/version"
3
-
4
- package = Rekey
1
+ require_relative "lib/rekey/version"
5
2
 
6
3
  Gem::Specification.new do |s|
7
- s.name = package_name
8
- s.version = package.const_get "VERSION"
9
4
  s.authors = ["Daniel Pepper"]
10
- s.summary = package.to_s
11
5
  s.description = "Reformat Enumerables into Hashes, using derived keys / values"
12
- s.homepage = "https://github.com/dpep/#{package_name}_rb"
6
+ s.files = `git ls-files * ':!:spec'`.split("\n")
7
+ s.homepage = "https://github.com/dpep/rekey_rb"
13
8
  s.license = "MIT"
14
- s.files = `git ls-files * ":!:spec"`.split("\n")
9
+ s.name = "rekey"
10
+ s.summary = s.description
11
+ s.version = Rekey::VERSION
12
+
13
+ s.metadata = {
14
+ "changelog_uri" => "#{s.homepage}/blob/main/CHANGELOG.md",
15
+ "rubygems_mfa_required" => "true",
16
+ "source_code_uri" => s.homepage,
17
+ }
15
18
 
16
- s.required_ruby_version = ">= 3"
19
+ s.required_ruby_version = ">= 3.2"
17
20
 
18
- s.add_runtime_dependency "pluckit"
21
+ s.add_dependency "pluckit", ">= 1.3"
19
22
 
20
23
  s.add_development_dependency "debug"
21
24
  s.add_development_dependency "rspec"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rekey
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '0'
18
+ version: '1.3'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '0'
25
+ version: '1.3'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +81,10 @@ files:
81
81
  homepage: https://github.com/dpep/rekey_rb
82
82
  licenses:
83
83
  - MIT
84
- metadata: {}
84
+ metadata:
85
+ changelog_uri: https://github.com/dpep/rekey_rb/blob/main/CHANGELOG.md
86
+ rubygems_mfa_required: 'true'
87
+ source_code_uri: https://github.com/dpep/rekey_rb
85
88
  rdoc_options: []
86
89
  require_paths:
87
90
  - lib
@@ -89,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
92
  requirements:
90
93
  - - ">="
91
94
  - !ruby/object:Gem::Version
92
- version: '3'
95
+ version: '3.2'
93
96
  required_rubygems_version: !ruby/object:Gem::Requirement
94
97
  requirements:
95
98
  - - ">="
96
99
  - !ruby/object:Gem::Version
97
100
  version: '0'
98
101
  requirements: []
99
- rubygems_version: 3.6.9
102
+ rubygems_version: 4.0.16
100
103
  specification_version: 4
101
- summary: Rekey
104
+ summary: Reformat Enumerables into Hashes, using derived keys / values
102
105
  test_files: []