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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 320458b0c0e09c8556129b456eb191ff588a6b2277b5da46a5273dc36c4f3a50
4
- data.tar.gz: 824f8c91fbe4749022a8a5f2caf6d6f76714a6d7faf747a4f25818342d5d5b39
3
+ metadata.gz: f3a8a85bd0554c198bd29acae4a9f4d5126fd34d9907dd3b9b8b65c03cc32f86
4
+ data.tar.gz: 580151bb2f1a764ad993d25ae0e615095c37b4d61a6f454b4d6e9be300e6ed39
5
5
  SHA512:
6
- metadata.gz: ac7ed45151941a1e124372ebfb1394fb8176f4703bc903fa634d3672a251c8a4e497f8555bc1433848512d7e8edb04926c8a043420d3337041c7fc00e9e7eebd
7
- data.tar.gz: b0d711b08f5ec75aa07ab009587784a926f2e5832a35037da89a96fa5d800a29e4e4b1c3beb81ba6b86b3d5821252aeda2ab2f124234f859af477cbeb186a8cb
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
- ## [Unreleased]
18
+ ## [0.6.0] - 12025-04-26
19
19
 
20
- ### Added
20
+ ### BREAKING CHANGES:
21
21
 
22
- ### Changed
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
- ### Removed
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.with_key { |k, v| "User #{k}: #{v[:name]}" }
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.4 development environment";
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
- (ruby_3_4.override {
23
+ (ruby_3_2.override {
24
24
  jemallocSupport = true;
25
25
  docSupport = false;
26
26
  })
@@ -258,60 +258,193 @@ class Hash
258
258
  alias_method :og_transform_values!, :transform_values!
259
259
 
260
260
  #
261
- # Transforms hash values while allowing access to keys via the chainable with_key method
261
+ # Returns a new hash with all values transformed by the block
262
262
  #
263
- # This method either performs a standard transform_values operation if a block is given,
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
- # @yield [value] Block to transform each value (standard behavior)
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, Enumerator] Result hash or Enumerator with with_key method
272
+ # @return [Hash] A new hash with transformed values
273
+ # @return [Enumerator] If no block is given
272
274
  #
273
- # @example Standard transform_values
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 Using with_key to access keys during transformation
278
- # {a: 1, b: 2}.transform_values.with_key { |v, k| "#{k}_#{v}" }
279
- # # => {a: "a_1", b: "b_2"}
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 transform_values_enumerator if block.nil?
283
+ def transform_values(with_key: false, &block)
284
+ return to_enum(:transform_values, with_key:) if block.nil?
283
285
 
284
- og_transform_values(&block)
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 hash values in place while allowing access to keys via the chainable with_key method
296
+ # Transforms all values in the hash in place
297
+ #
298
+ # Enhances Ruby's standard transform_values! with key access capability.
289
299
  #
290
- # This method either performs a standard transform_values! operation if a block is given,
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 to transform each value (standard behavior)
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, Enumerator]
299
- # Original hash with transformed values or Enumerator with with_key method
307
+ # @return [self] The transformed hash
308
+ # @return [Enumerator] If no block is given
300
309
  #
301
- # @example Standard transform_values!
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 Using with_key to access keys during in-place transformation
316
+ # @example With key access
307
317
  # hash = {a: 1, b: 2}
308
- # hash.transform_values!.with_key { |v, k| "#{k}_#{v}" }
309
- # # => {a: "a_1", b: "b_2"}
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 transform_values_bang_enumerator if block.nil?
322
+ def transform_values!(with_key: false, &block)
323
+ return to_enum(:transform_values!, with_key:) if block.nil?
313
324
 
314
- og_transform_values!(&block)
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
@@ -7,5 +7,5 @@
7
7
  #
8
8
  module Everythingrb
9
9
  # Current version of the everythingrb gem
10
- VERSION = "0.5.0"
10
+ VERSION = "0.6.0"
11
11
  end
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.5.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-17 00:00:00.000000000 Z
11
+ date: 2025-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ostruct