everythingrb 0.5.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +21 -4
- data/README.md +3 -2
- data/flake.nix +2 -2
- data/lib/everythingrb/hash.rb +160 -63
- data/lib/everythingrb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3a8a85bd0554c198bd29acae4a9f4d5126fd34d9907dd3b9b8b65c03cc32f86
|
4
|
+
data.tar.gz: 580151bb2f1a764ad993d25ae0e615095c37b4d61a6f454b4d6e9be300e6ed39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a10e0a0980a4a061d8103f0ec99523094320b432bf5c15e367313d0be06bdadb22ee0fcaae037fdbb233501aa48081a84502c03c74a7e786e573f1679fb81549
|
7
|
+
data.tar.gz: e6a2368422b235a1d5859f0afb3dbc908d777d5098296cf64f10cd212f2e6d23f7dc6a5d6cb740e0a71da833536bcf7351934895ae73294a62026ac052bb3ee9
|
data/CHANGELOG.md
CHANGED
@@ -15,13 +15,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
15
15
|
### Removed
|
16
16
|
-->
|
17
17
|
|
18
|
-
## [
|
18
|
+
## [0.6.0] - 12025-04-26
|
19
19
|
|
20
|
-
###
|
20
|
+
### BREAKING CHANGES:
|
21
21
|
|
22
|
-
|
22
|
+
- **Replaced method-based `with_key` approach with direct parameter**:
|
23
|
+
The chainable `.with_key` method approach has been replaced with a more straightforward parameter-based approach.
|
23
24
|
|
24
|
-
|
25
|
+
**Before:**
|
26
|
+
```ruby
|
27
|
+
hash.transform_values.with_key { |value, key| "#{key}:#{value}" }
|
28
|
+
hash.transform_values!.with_key { |value, key| "#{key}:#{value}" }
|
29
|
+
```
|
30
|
+
|
31
|
+
**After:**
|
32
|
+
```ruby
|
33
|
+
hash.transform_values(with_key: true) { |value, key| "#{key}:#{value}" }
|
34
|
+
hash.transform_values!(with_key: true) { |value, key| "#{key}:#{value}" }
|
35
|
+
```
|
36
|
+
|
37
|
+
### Added:
|
38
|
+
|
39
|
+
- Added ActiveSupport integration for deep transforms with key access:
|
40
|
+
- `Hash#deep_transform_values(with_key: true)`
|
41
|
+
- `Hash#deep_transform_values!(with_key: true)`
|
25
42
|
|
26
43
|
## [0.5.0] - 12025-04-17
|
27
44
|
|
data/README.md
CHANGED
@@ -7,8 +7,9 @@
|
|
7
7
|
Super handy extensions to Ruby core classes that make your code more expressive, readable, and fun to write.
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
# Instead of this:
|
11
10
|
users = [{ name: "Alice", role: "admin" }, { name: "Bob", role: "user" }]
|
11
|
+
|
12
|
+
# Instead of this:
|
12
13
|
admin_names = users.select { |u| u[:role] == "admin" }.map { |u| u[:name] }.join(", ")
|
13
14
|
|
14
15
|
# Write this:
|
@@ -141,7 +142,7 @@ stats[:server][:region][:us_east][:errors] << "Connection timeout"
|
|
141
142
|
# No need to initialize each level first!
|
142
143
|
|
143
144
|
# Transform values with access to keys
|
144
|
-
users.transform_values
|
145
|
+
users.transform_values(with_key: true) { |v, k| "User #{k}: #{v[:name]}" }
|
145
146
|
|
146
147
|
# Find values based on conditions
|
147
148
|
users.values_where { |k, v| v[:role] == "admin" }
|
data/flake.nix
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
description = "Ruby 3.
|
2
|
+
description = "Ruby 3.2 development environment";
|
3
3
|
|
4
4
|
inputs = {
|
5
5
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
@@ -20,7 +20,7 @@
|
|
20
20
|
{
|
21
21
|
devShells.default = pkgs.mkShell {
|
22
22
|
buildInputs = with pkgs; [
|
23
|
-
(
|
23
|
+
(ruby_3_2.override {
|
24
24
|
jemallocSupport = true;
|
25
25
|
docSupport = false;
|
26
26
|
})
|
data/lib/everythingrb/hash.rb
CHANGED
@@ -258,60 +258,193 @@ class Hash
|
|
258
258
|
alias_method :og_transform_values!, :transform_values!
|
259
259
|
|
260
260
|
#
|
261
|
-
#
|
261
|
+
# Returns a new hash with all values transformed by the block
|
262
262
|
#
|
263
|
-
#
|
264
|
-
# or returns an enumerator with a with_key method that passes both the key and value
|
265
|
-
# to the block.
|
263
|
+
# Enhances Ruby's standard transform_values with key access capability.
|
266
264
|
#
|
267
|
-
# @
|
265
|
+
# @param with_key [Boolean] Whether to yield both value and key to the block
|
266
|
+
#
|
267
|
+
# @yield [value, key] Block that transforms each value
|
268
268
|
# @yieldparam value [Object] The value to transform
|
269
|
+
# @yieldparam key [Object] The corresponding key (only if with_key: true)
|
269
270
|
# @yieldreturn [Object] The transformed value
|
270
271
|
#
|
271
|
-
# @return [Hash
|
272
|
+
# @return [Hash] A new hash with transformed values
|
273
|
+
# @return [Enumerator] If no block is given
|
272
274
|
#
|
273
|
-
# @example Standard
|
275
|
+
# @example Standard usage
|
274
276
|
# {a: 1, b: 2}.transform_values { |v| v * 2 }
|
275
277
|
# # => {a: 2, b: 4}
|
276
278
|
#
|
277
|
-
# @example
|
278
|
-
# {a: 1, b: 2}.transform_values
|
279
|
-
# # => {a: "
|
279
|
+
# @example With key access
|
280
|
+
# {a: 1, b: 2}.transform_values(with_key: true) { |v, k| "#{k}:#{v}" }
|
281
|
+
# # => {a: "a:1", b: "b:2"}
|
280
282
|
#
|
281
|
-
def transform_values(&block)
|
282
|
-
return
|
283
|
+
def transform_values(with_key: false, &block)
|
284
|
+
return to_enum(:transform_values, with_key:) if block.nil?
|
283
285
|
|
284
|
-
|
286
|
+
if with_key
|
287
|
+
each_pair.with_object({}) do |(key, value), output|
|
288
|
+
output[key] = block.call(value, key)
|
289
|
+
end
|
290
|
+
else
|
291
|
+
og_transform_values(&block)
|
292
|
+
end
|
285
293
|
end
|
286
294
|
|
287
295
|
#
|
288
|
-
# Transforms
|
296
|
+
# Transforms all values in the hash in place
|
297
|
+
#
|
298
|
+
# Enhances Ruby's standard transform_values! with key access capability.
|
289
299
|
#
|
290
|
-
#
|
291
|
-
# or returns an enumerator with a with_key method that passes both the key and value
|
292
|
-
# to the block, updating the hash in place.
|
300
|
+
# @param with_key [Boolean] Whether to yield both value and key to the block
|
293
301
|
#
|
294
|
-
# @yield [value] Block
|
302
|
+
# @yield [value, key] Block that transforms each value
|
295
303
|
# @yieldparam value [Object] The value to transform
|
304
|
+
# @yieldparam key [Object] The corresponding key (only if with_key: true)
|
296
305
|
# @yieldreturn [Object] The transformed value
|
297
306
|
#
|
298
|
-
# @return [self
|
299
|
-
#
|
307
|
+
# @return [self] The transformed hash
|
308
|
+
# @return [Enumerator] If no block is given
|
300
309
|
#
|
301
|
-
# @example Standard
|
310
|
+
# @example Standard usage
|
302
311
|
# hash = {a: 1, b: 2}
|
303
312
|
# hash.transform_values! { |v| v * 2 }
|
304
313
|
# # => {a: 2, b: 4}
|
314
|
+
# # hash is now {a: 2, b: 4}
|
305
315
|
#
|
306
|
-
# @example
|
316
|
+
# @example With key access
|
307
317
|
# hash = {a: 1, b: 2}
|
308
|
-
# hash.transform_values
|
309
|
-
# # => {a: "
|
318
|
+
# hash.transform_values!(with_key: true) { |v, k| "#{k}:#{v}" }
|
319
|
+
# # => {a: "a:1", b: "b:2"}
|
320
|
+
# # hash is now {a: "a:1", b: "b:2"}
|
310
321
|
#
|
311
|
-
def transform_values!(&block)
|
312
|
-
return
|
322
|
+
def transform_values!(with_key: false, &block)
|
323
|
+
return to_enum(:transform_values!, with_key:) if block.nil?
|
313
324
|
|
314
|
-
|
325
|
+
if with_key
|
326
|
+
each_pair do |key, value|
|
327
|
+
self[key] = block.call(value, key)
|
328
|
+
end
|
329
|
+
else
|
330
|
+
og_transform_values!(&block)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# ActiveSupport integrations
|
335
|
+
if defined?(ActiveSupport)
|
336
|
+
# Allows calling original method. See below
|
337
|
+
alias_method :og_deep_transform_values, :deep_transform_values
|
338
|
+
|
339
|
+
# Allows calling original method. See below
|
340
|
+
alias_method :og_deep_transform_values!, :deep_transform_values!
|
341
|
+
|
342
|
+
#
|
343
|
+
# Recursively transforms all values in the hash and nested structures
|
344
|
+
#
|
345
|
+
# Walks through the hash and all nested hashes/arrays and yields each non-hash and
|
346
|
+
# non-array value to the block, replacing it with the block's return value.
|
347
|
+
#
|
348
|
+
# @param with_key [Boolean] Whether to yield both value and key to the block
|
349
|
+
#
|
350
|
+
# @yield [value, key] Block that transforms each value
|
351
|
+
# @yieldparam value [Object] The value to transform
|
352
|
+
# @yieldparam key [Object] The corresponding key (only if with_key: true)
|
353
|
+
# @yieldreturn [Object] The transformed value
|
354
|
+
#
|
355
|
+
# @return [Hash] A new hash with all values recursively transformed
|
356
|
+
# @return [Enumerator] If no block is given
|
357
|
+
#
|
358
|
+
# @example Basic usage
|
359
|
+
# hash = {a: 1, b: {c: 2, d: [3, 4]}}
|
360
|
+
# hash.deep_transform_values { |v| v * 2 }
|
361
|
+
# # => {a: 2, b: {c: 4, d: [6, 8]}}
|
362
|
+
#
|
363
|
+
# @example With key access
|
364
|
+
# hash = {a: 1, b: {c: 2}}
|
365
|
+
# hash.deep_transform_values(with_key: true) { |v, k| "#{k}:#{v}" }
|
366
|
+
# # => {a: "a:1", b: {c: "c:2"}}
|
367
|
+
#
|
368
|
+
def deep_transform_values(with_key: false, &block)
|
369
|
+
return to_enum(:deep_transform_values, with_key:) if block.nil?
|
370
|
+
|
371
|
+
if with_key
|
372
|
+
_deep_transform_values_with_key(self, nil, &block)
|
373
|
+
else
|
374
|
+
og_deep_transform_values(&block)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
#
|
379
|
+
# Recursively transforms all values in the hash and nested structures in place
|
380
|
+
#
|
381
|
+
# Same as #deep_transform_values but modifies the hash in place.
|
382
|
+
#
|
383
|
+
# @param with_key [Boolean] Whether to yield both value and key to the block
|
384
|
+
#
|
385
|
+
# @yield [value, key] Block that transforms each value
|
386
|
+
# @yieldparam value [Object] The value to transform
|
387
|
+
# @yieldparam key [Object] The corresponding key (only if with_key: true)
|
388
|
+
# @yieldreturn [Object] The transformed value
|
389
|
+
#
|
390
|
+
# @return [self] The transformed hash
|
391
|
+
# @return [Enumerator] If no block is given
|
392
|
+
#
|
393
|
+
# @example Basic usage
|
394
|
+
# hash = {a: 1, b: {c: 2, d: [3, 4]}}
|
395
|
+
# hash.deep_transform_values! { |v| v * 2 }
|
396
|
+
# # => {a: 2, b: {c: 4, d: [6, 8]}}
|
397
|
+
# # hash is now {a: 2, b: {c: 4, d: [6, 8]}}
|
398
|
+
#
|
399
|
+
# @example With key access
|
400
|
+
# hash = {a: 1, b: {c: 2}}
|
401
|
+
# hash.deep_transform_values!(with_key: true) { |v, k| "#{k}:#{v}" }
|
402
|
+
# # => {a: "a:1", b: {c: "c:2"}}
|
403
|
+
# # hash is now {a: "a:1", b: {c: "c:2"}}
|
404
|
+
#
|
405
|
+
def deep_transform_values!(with_key: false, &block)
|
406
|
+
return to_enum(:deep_transform_values!, with_key:) if block.nil?
|
407
|
+
|
408
|
+
if with_key
|
409
|
+
_deep_transform_values_with_key!(self, nil, &block)
|
410
|
+
else
|
411
|
+
og_deep_transform_values!(&block)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
private
|
416
|
+
|
417
|
+
# https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb#L25
|
418
|
+
def _deep_transform_values_with_key(object, key, &block)
|
419
|
+
case object
|
420
|
+
when Hash
|
421
|
+
object.transform_values(with_key: true) do |value, key|
|
422
|
+
_deep_transform_values_with_key(value, key, &block)
|
423
|
+
end
|
424
|
+
when Array
|
425
|
+
object.map do |value|
|
426
|
+
_deep_transform_values_with_key(value, nil, &block)
|
427
|
+
end
|
428
|
+
else
|
429
|
+
block.call(object, key)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
# https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb#L36
|
434
|
+
def _deep_transform_values_with_key!(object, key, &block)
|
435
|
+
case object
|
436
|
+
when Hash
|
437
|
+
object.transform_values!(with_key: true) do |value, key|
|
438
|
+
_deep_transform_values_with_key!(value, key, &block)
|
439
|
+
end
|
440
|
+
when Array
|
441
|
+
object.map! do |value|
|
442
|
+
_deep_transform_values_with_key!(value, nil, &block)
|
443
|
+
end
|
444
|
+
else
|
445
|
+
block.call(object, key)
|
446
|
+
end
|
447
|
+
end
|
315
448
|
end
|
316
449
|
|
317
450
|
#
|
@@ -528,40 +661,4 @@ class Hash
|
|
528
661
|
self[new_key] = delete(old_key)
|
529
662
|
self
|
530
663
|
end
|
531
|
-
|
532
|
-
private
|
533
|
-
|
534
|
-
def transform_values_enumerator
|
535
|
-
original_hash = self
|
536
|
-
enum = to_enum(:transform_values)
|
537
|
-
|
538
|
-
# Add the with_key method directly to the enum
|
539
|
-
enum.define_singleton_method(:with_key) do |&block|
|
540
|
-
raise ArgumentError, "Missing block for Hash#transform_values.with_key" if block.nil?
|
541
|
-
|
542
|
-
original_hash.each_pair.with_object({}) do |(key, value), output|
|
543
|
-
output[key] = block.call(value, key)
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
enum
|
548
|
-
end
|
549
|
-
|
550
|
-
def transform_values_bang_enumerator
|
551
|
-
original_hash = self
|
552
|
-
enum = to_enum(:transform_values!)
|
553
|
-
|
554
|
-
# Add the with_key method directly to the enum
|
555
|
-
enum.define_singleton_method(:with_key) do |&block|
|
556
|
-
raise ArgumentError, "Missing block for Hash#transform_values!.with_key" if block.nil?
|
557
|
-
|
558
|
-
original_hash.each_pair do |key, value|
|
559
|
-
original_hash[key] = block.call(value, key)
|
560
|
-
end
|
561
|
-
|
562
|
-
original_hash
|
563
|
-
end
|
564
|
-
|
565
|
-
enum
|
566
|
-
end
|
567
664
|
end
|
data/lib/everythingrb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: everythingrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ostruct
|