everythingrb 0.3.0 → 0.4.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 +37 -4
- data/README.md +47 -0
- data/lib/everythingrb/all.rb +11 -0
- data/lib/everythingrb/{core/array.rb → array.rb} +10 -11
- data/lib/everythingrb/data.rb +23 -0
- data/lib/everythingrb/{core/enumerable.rb → enumerable.rb} +7 -5
- data/lib/everythingrb/{core/hash.rb → hash.rb} +169 -23
- data/lib/everythingrb/{core/module.rb → module.rb} +6 -4
- data/lib/everythingrb/{core/ostruct.rb → ostruct.rb} +25 -4
- data/lib/everythingrb/prelude.rb +30 -0
- data/lib/everythingrb/{core/string.rb → string.rb} +10 -7
- data/lib/everythingrb/struct.rb +31 -0
- data/lib/everythingrb/{core/symbol.rb → symbol.rb} +4 -1
- data/lib/everythingrb/version.rb +1 -1
- data/lib/everythingrb.rb +2 -35
- metadata +15 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfa8c1ad4940f61e609e0b70618493a050979540beb9e3388828d9c8741f9103
|
4
|
+
data.tar.gz: a4851a664e888577d68a01fc9830d9d8c812ff5758edce994eacd0f1440887f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd750b905857c86db3cdd8c054c50a7900e2ef194fdd51df69bd35267f0f947bbb93dca3df9bb7596758b15a5312203cb02875ff99c90eca03aab7d63c064e79
|
7
|
+
data.tar.gz: 6c9c6198b3ef913c4cfebcae52cc85573a499a29b4d21eb2826e22f13dfd58f20fa96333faa92a3ff2d7e88ad38df97247d1836b7b554eb859e59dcd17f03bd2
|
data/CHANGELOG.md
CHANGED
@@ -23,6 +23,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
23
23
|
|
24
24
|
### Removed
|
25
25
|
|
26
|
+
## [0.4.0]
|
27
|
+
|
28
|
+
### Added
|
29
|
+
|
30
|
+
- Added new `Hash` methods for renaming keys:
|
31
|
+
- `#rename_key` - Renames a key in the hash while preserving the original order of elements
|
32
|
+
- `#rename_key!` - Same as `#rename_key` but modifies the hash in place
|
33
|
+
- `#rename_keys` - Renames multiple keys in the hash while preserving the original order of elements
|
34
|
+
- `#rename_keys!` - Same as `#rename_keys` but modifies the hash in place
|
35
|
+
- `#rename_key_unordered` - Renames a key without preserving element order (faster operation)
|
36
|
+
- `#rename_key_unordered!` - Same as `#rename_key_unordered` but modifies the hash in place
|
37
|
+
- Added `to_deep_h` to core Ruby classes for consistent deep hash conversion:
|
38
|
+
- `Struct#to_deep_h` - Recursively converts Struct objects and all nested values to hashes
|
39
|
+
- `OpenStruct#to_deep_h` - Recursively converts OpenStruct objects and all nested values to hashes
|
40
|
+
- `Data#to_deep_h` - Recursively converts Data objects and all nested values to hashes
|
41
|
+
- Added `depth` parameter to `Hash.new_nested_hash` to control nesting behaviors
|
42
|
+
|
43
|
+
### Changed
|
44
|
+
|
45
|
+
- Reorganized internal file structure for better modularity with full backward compatibility
|
46
|
+
- Updated documentation headers to each module file explaining available extensions
|
47
|
+
|
48
|
+
### Removed
|
49
|
+
|
50
|
+
## [0.3.1] - 12025-04-09
|
51
|
+
|
52
|
+
### Added
|
53
|
+
|
54
|
+
### Changed
|
55
|
+
|
56
|
+
- Fixed `Hash#value_where` error when nothing is found
|
57
|
+
|
58
|
+
### Removed
|
59
|
+
|
26
60
|
## [0.3.0] - 12025-04-09
|
27
61
|
|
28
62
|
### Added
|
@@ -64,7 +98,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
64
98
|
|
65
99
|
- Added `Symbol#with_quotes` and `Symbol#in_quotes`
|
66
100
|
|
67
|
-
|
68
101
|
## [0.2.2] - 12025-03-03
|
69
102
|
|
70
103
|
### Added
|
@@ -84,7 +117,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
84
117
|
|
85
118
|
- Removed `Data` definition check for `to_istruct`
|
86
119
|
|
87
|
-
|
88
120
|
## [0.2.0] - 12025-02-17
|
89
121
|
|
90
122
|
### Added
|
@@ -109,7 +141,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
109
141
|
|
110
142
|
- Separated out tests that require `ActiveSupport` into their own test process. Files that end with `_active_support` will be tested separately with ActiveSupport loaded
|
111
143
|
|
112
|
-
|
113
144
|
## [0.1.1] - 12025-02-07
|
114
145
|
|
115
146
|
### Added
|
@@ -139,7 +170,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
139
170
|
|
140
171
|
- Added alias `each` to `each_pair` in OpenStruct for better enumerable compatibility
|
141
172
|
|
142
|
-
[unreleased]: https://github.com/itsthedevman/everythingrb/compare/v0.
|
173
|
+
[unreleased]: https://github.com/itsthedevman/everythingrb/compare/v0.4.0...HEAD
|
174
|
+
[0.4.0]: https://github.com/itsthedevman/everythingrb/compare/v0.3.1...v0.4.0
|
175
|
+
[0.3.1]: https://github.com/itsthedevman/everythingrb/compare/v0.3.0...v0.3.1
|
143
176
|
[0.3.0]: https://github.com/itsthedevman/everythingrb/compare/v0.2.5...v0.3.0
|
144
177
|
[0.2.5]: https://github.com/itsthedevman/everythingrb/compare/v0.2.4...v0.2.5
|
145
178
|
[0.2.4]: https://github.com/itsthedevman/everythingrb/compare/v0.2.3...v0.2.4
|
data/README.md
CHANGED
@@ -25,6 +25,53 @@ gem "everythingrb"
|
|
25
25
|
gem install everythingrb
|
26
26
|
```
|
27
27
|
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
There are two ways to use EverythingRB:
|
31
|
+
|
32
|
+
### Load Everything (Default)
|
33
|
+
|
34
|
+
The simplest approach - just require and go:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require "everythingrb"
|
38
|
+
|
39
|
+
# Now you have access to all extensions!
|
40
|
+
users = [{name: "Alice"}, {name: "Bob"}]
|
41
|
+
users.key_map(:name).join(", ") # => "Alice, Bob"
|
42
|
+
|
43
|
+
config = {server: {port: 443}}.to_ostruct
|
44
|
+
config.server.port # => 443
|
45
|
+
```
|
46
|
+
|
47
|
+
### Cherry-Pick Extensions
|
48
|
+
|
49
|
+
If you only need specific extensions, you can load just what you want:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
require "everythingrb/prelude" # Required base module
|
53
|
+
require "everythingrb/array" # Just Array extensions
|
54
|
+
require "everythingrb/string" # Just String extensions
|
55
|
+
|
56
|
+
# Now you have access to only the extensions you loaded
|
57
|
+
["a", "b"].join_map(" | ") { |s| s.upcase } # => "A | B"
|
58
|
+
'{"name": "Alice"}'.to_ostruct.name # => "Alice"
|
59
|
+
|
60
|
+
# But Hash extensions aren't loaded yet
|
61
|
+
{}.to_ostruct # => NoMethodError
|
62
|
+
```
|
63
|
+
|
64
|
+
Available modules:
|
65
|
+
- `array`: Array extensions (join_map, key_map, etc.)
|
66
|
+
- `data`: Data extensions (to_deep_h)
|
67
|
+
- `enumerable`: Enumerable extensions (join_map, group_by_key)
|
68
|
+
- `hash`: Hash extensions (to_ostruct, deep_freeze, etc.)
|
69
|
+
- `module`: Extensions like attr_predicate
|
70
|
+
- `ostruct`: OpenStruct extensions (map, join_map, etc.)
|
71
|
+
- `string`: String extensions (to_h, to_ostruct, etc.)
|
72
|
+
- `struct`: Struct extensions (to_deep_h)
|
73
|
+
- `symbol`: Symbol extensions (with_quotes)
|
74
|
+
|
28
75
|
## What's Included
|
29
76
|
|
30
77
|
EverythingRB extends Ruby's core classes with intuitive methods that simplify common patterns.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "array"
|
4
|
+
require_relative "data"
|
5
|
+
require_relative "enumerable"
|
6
|
+
require_relative "hash"
|
7
|
+
require_relative "module"
|
8
|
+
require_relative "ostruct"
|
9
|
+
require_relative "string"
|
10
|
+
require_relative "struct"
|
11
|
+
require_relative "symbol"
|
@@ -3,18 +3,17 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core Array class
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #join_map: Combine filter_map and join operations in one step
|
8
|
+
# - #key_map, #dig_map: Extract values from arrays of hashes
|
9
|
+
# - #deep_freeze: Recursively freeze array and contents
|
10
|
+
# - #compact_prefix, #compact_suffix, #trim_nils: Clean up array boundaries
|
11
|
+
# - ActiveSupport integrations: #trim_blanks and more when ActiveSupport is loaded
|
8
12
|
#
|
9
|
-
# @example
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# numbers.join_map(", ") { |n| "odd: #{n}" if n&.odd? }
|
14
|
-
# # => "odd: 1, odd: 3"
|
15
|
-
#
|
16
|
-
# users = [{name: "Alice", role: "admin"}, {name: "Bob", role: "user"}]
|
17
|
-
# users.key_map(:name) # => ["Alice", "Bob"]
|
13
|
+
# @example
|
14
|
+
# require "everythingrb/array"
|
15
|
+
# ["foo", nil, "bar"].join_map(", ") { |s| s&.upcase } # => "FOO, BAR"
|
16
|
+
# [{name: "Alice"}, {name: "Bob"}].key_map(:name) # => ["Alice", "Bob"]
|
18
17
|
#
|
19
18
|
class Array
|
20
19
|
#
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Extensions to Ruby's core Data class
|
5
|
+
#
|
6
|
+
# Provides:
|
7
|
+
# - #to_deep_h: Recursively convert to hash with all nested objects
|
8
|
+
#
|
9
|
+
class Data
|
10
|
+
#
|
11
|
+
# Recursively converts the Data object and all nested objects to hashes
|
12
|
+
#
|
13
|
+
# @return [Hash] A deeply converted hash of the Data object
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# Person = Data.define(:name, :profile)
|
17
|
+
# person = Person.new(name: "Alice", profile: {roles: ["admin"]})
|
18
|
+
# person.to_deep_h # => {name: "Alice", profile: {roles: ["admin"]}}
|
19
|
+
#
|
20
|
+
def to_deep_h
|
21
|
+
to_h.to_deep_h
|
22
|
+
end
|
23
|
+
end
|
@@ -3,12 +3,14 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core Enumerable module
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #join_map: Combine filter_map and join operations
|
8
|
+
# - #group_by_key: Group elements by a given key or nested keys
|
8
9
|
#
|
9
|
-
# @example
|
10
|
-
#
|
11
|
-
# # => "item-2 | item-4"
|
10
|
+
# @example
|
11
|
+
# require "everythingrb/enumerable"
|
12
|
+
# (1..5).join_map(" | ") { |n| "item-#{n}" if n.even? } # => "item-2 | item-4"
|
13
|
+
# users.group_by_key(:role) # Groups users by their role
|
12
14
|
#
|
13
15
|
module Enumerable
|
14
16
|
#
|
@@ -3,17 +3,19 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core Hash class
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #to_struct, #to_ostruct, #to_istruct: Convert hashes to different structures
|
8
|
+
# - #join_map: Combine filter_map and join operations
|
9
|
+
# - #deep_freeze: Recursively freeze hash and contents
|
10
|
+
# - #transform_values.with_key: Transform values with access to keys
|
11
|
+
# - #value_where, #values_where: Find values based on conditions
|
12
|
+
# - #rename_key, #rename_keys: Rename hash keys while preserving order
|
13
|
+
# - ::new_nested_hash: Create automatically nesting hashes
|
8
14
|
#
|
9
|
-
# @example
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# # Filtering and joining hash entries
|
15
|
-
# { a: 1, b: nil, c: 3 }.join_map(", ") { |k, v| "#{k}:#{v}" if v }
|
16
|
-
# # => "a:1, c:3"
|
15
|
+
# @example
|
16
|
+
# require "everythingrb/hash"
|
17
|
+
# config = {server: {port: 443}}.to_ostruct
|
18
|
+
# config.server.port # => 443
|
17
19
|
#
|
18
20
|
class Hash
|
19
21
|
#
|
@@ -33,26 +35,49 @@ class Hash
|
|
33
35
|
# Creates a new Hash that automatically initializes missing keys with nested hashes
|
34
36
|
#
|
35
37
|
# This method creates a hash where any missing key access will automatically
|
36
|
-
# create another nested hash with the same behavior
|
37
|
-
#
|
38
|
+
# create another nested hash with the same behavior. You can control the nesting
|
39
|
+
# depth with the depth parameter.
|
40
|
+
#
|
41
|
+
# @param depth [Integer, nil] The maximum nesting depth for automatic hash creation
|
42
|
+
# When nil (default), creates unlimited nesting depth
|
43
|
+
# When 0, behaves like a regular hash (returns nil for missing keys)
|
44
|
+
# When > 0, automatically creates hashes only up to the specified level
|
38
45
|
#
|
39
|
-
# @return [Hash] A hash that
|
46
|
+
# @return [Hash] A hash that creates nested hashes for missing keys
|
40
47
|
#
|
41
|
-
# @example
|
48
|
+
# @example Unlimited nesting (default behavior)
|
42
49
|
# users = Hash.new_nested_hash
|
43
50
|
# users[:john][:role] = "admin" # No need to initialize users[:john] first
|
44
51
|
# users # => {john: {role: "admin"}}
|
45
52
|
#
|
46
53
|
# @example Deep nesting without initialization
|
47
54
|
# stats = Hash.new_nested_hash
|
48
|
-
#
|
49
|
-
# stats # => {server: {region: {us_east: {errors: ["
|
50
|
-
#
|
51
|
-
# @
|
52
|
-
#
|
53
|
-
#
|
54
|
-
|
55
|
-
|
55
|
+
# stats[:server][:region][:us_east][:errors] = ["Error"]
|
56
|
+
# stats # => {server: {region: {us_east: {errors: ["Error"]}}}}
|
57
|
+
#
|
58
|
+
# @example Limited nesting depth
|
59
|
+
# hash = Hash.new_nested_hash(depth: 1)
|
60
|
+
# hash[:user][:name] = "Alice" # Works fine - only one level of auto-creation
|
61
|
+
#
|
62
|
+
# # This pattern works correctly with limited nesting:
|
63
|
+
# (hash[:user][:roles] ||= []) << "admin"
|
64
|
+
# hash # => {user: {name: "Alice", roles: ["admin"]}}
|
65
|
+
#
|
66
|
+
# @note While unlimited nesting is convenient, it can interfere with common Ruby
|
67
|
+
# patterns like ||= when initializing values at deep depths. Use the depth
|
68
|
+
# parameter to control this behavior.
|
69
|
+
#
|
70
|
+
def self.new_nested_hash(depth: nil)
|
71
|
+
new do |hash, key|
|
72
|
+
next if depth == 0
|
73
|
+
|
74
|
+
hash[key] =
|
75
|
+
if depth.nil?
|
76
|
+
new_nested_hash
|
77
|
+
else
|
78
|
+
new_nested_hash(depth: depth - 1)
|
79
|
+
end
|
80
|
+
end
|
56
81
|
end
|
57
82
|
|
58
83
|
#
|
@@ -310,7 +335,7 @@ class Hash
|
|
310
335
|
def value_where(&block)
|
311
336
|
return to_enum(:value_where) if block.nil?
|
312
337
|
|
313
|
-
find(&block)
|
338
|
+
find(&block)&.last
|
314
339
|
end
|
315
340
|
|
316
341
|
#
|
@@ -339,6 +364,127 @@ class Hash
|
|
339
364
|
select(&block).values
|
340
365
|
end
|
341
366
|
|
367
|
+
#
|
368
|
+
# Renames a key in the hash while preserving the original order of elements
|
369
|
+
#
|
370
|
+
# @param old_key [Object] The key to rename
|
371
|
+
# @param new_key [Object] The new key to use
|
372
|
+
#
|
373
|
+
# @return [Hash] A new hash with the key renamed
|
374
|
+
#
|
375
|
+
# @example Renames a single key
|
376
|
+
# {a: 1, b: 2, c: 3}.rename_key(:b, :middle)
|
377
|
+
# # => {a: 1, middle: 2, c: 3}
|
378
|
+
#
|
379
|
+
def rename_key(old_key, new_key)
|
380
|
+
rename_keys(old_key => new_key)
|
381
|
+
end
|
382
|
+
|
383
|
+
#
|
384
|
+
# Renames a key in the hash in place while preserving the original order of elements
|
385
|
+
#
|
386
|
+
# @param old_key [Object] The key to rename
|
387
|
+
# @param new_key [Object] The new key to use
|
388
|
+
#
|
389
|
+
# @return [self] The modified hash
|
390
|
+
#
|
391
|
+
# @example Renames a key in place
|
392
|
+
# hash = {a: 1, b: 2, c: 3}
|
393
|
+
# hash.rename_key!(:b, :middle)
|
394
|
+
# # => {a: 1, middle: 2, c: 3}
|
395
|
+
#
|
396
|
+
def rename_key!(old_key, new_key)
|
397
|
+
rename_keys!(old_key => new_key)
|
398
|
+
end
|
399
|
+
|
400
|
+
#
|
401
|
+
# Renames multiple keys in the hash while preserving the original order of elements
|
402
|
+
#
|
403
|
+
# This method maintains the original order of all keys in the hash, renaming
|
404
|
+
# only the specified keys while keeping their positions unchanged.
|
405
|
+
#
|
406
|
+
# @param keys [Hash] A mapping of old_key => new_key pairs
|
407
|
+
#
|
408
|
+
# @return [Hash] A new hash with keys renamed
|
409
|
+
#
|
410
|
+
# @example Renames multiple keys
|
411
|
+
# {a: 1, b: 2, c: 3, d: 4}.rename_keys(a: :first, c: :third)
|
412
|
+
# # => {first: 1, b: 2, third: 3, d: 4}
|
413
|
+
#
|
414
|
+
def rename_keys(**keys)
|
415
|
+
# I tried multiple different ways to rename the key while preserving the order, this was the fastest
|
416
|
+
transform_keys do |key|
|
417
|
+
keys.key?(key) ? keys[key] : key
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
#
|
422
|
+
# Renames multiple keys in the hash in place while preserving the original order of elements
|
423
|
+
#
|
424
|
+
# This method maintains the original order of all keys in the hash, renaming
|
425
|
+
# only the specified keys while keeping their positions unchanged.
|
426
|
+
#
|
427
|
+
# @param keys [Hash] A mapping of old_key => new_key pairs
|
428
|
+
#
|
429
|
+
# @return [self] The modified hash
|
430
|
+
#
|
431
|
+
# @example Rename multiple keys in place
|
432
|
+
# hash = {a: 1, b: 2, c: 3, d: 4}
|
433
|
+
# hash.rename_keys!(a: :first, c: :third)
|
434
|
+
# # => {first: 1, b: 2, third: 3, d: 4}
|
435
|
+
#
|
436
|
+
def rename_keys!(**keys)
|
437
|
+
# I tried multiple different ways to rename the key while preserving the order, this was the fastest
|
438
|
+
transform_keys! do |key|
|
439
|
+
keys.key?(key) ? keys[key] : key
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
#
|
444
|
+
# Renames a key in the hash without preserving element order (faster)
|
445
|
+
#
|
446
|
+
# This method is significantly faster than #rename_key but does not
|
447
|
+
# guarantee that the order of elements in the hash will be preserved.
|
448
|
+
#
|
449
|
+
# @param old_key [Object] The key to rename
|
450
|
+
# @param new_key [Object] The new key to use
|
451
|
+
#
|
452
|
+
# @return [Hash] A new hash with the key renamed
|
453
|
+
#
|
454
|
+
# @example Rename a single key without preserving order
|
455
|
+
# {a: 1, b: 2, c: 3}.rename_key_unordered(:b, :middle)
|
456
|
+
# # => {a: 1, c: 3, middle: 2} # Order may differ
|
457
|
+
#
|
458
|
+
def rename_key_unordered(old_key, new_key)
|
459
|
+
# Fun thing I learned. For small hashes, using #except is 1.5x faster than using dup and delete.
|
460
|
+
# But as the hash becomes larger, the performance improvements become diminished until they're roughly the same.
|
461
|
+
# Neat!
|
462
|
+
hash = except(old_key)
|
463
|
+
hash[new_key] = self[old_key]
|
464
|
+
hash
|
465
|
+
end
|
466
|
+
|
467
|
+
#
|
468
|
+
# Renames a key in the hash in place without preserving element order (faster)
|
469
|
+
#
|
470
|
+
# This method is significantly faster than #rename_key! but does not
|
471
|
+
# guarantee that the order of elements in the hash will be preserved.
|
472
|
+
#
|
473
|
+
# @param old_key [Object] The key to rename
|
474
|
+
# @param new_key [Object] The new key to use
|
475
|
+
#
|
476
|
+
# @return [self] The modified hash
|
477
|
+
#
|
478
|
+
# @example Rename a key in place without preserving order
|
479
|
+
# hash = {a: 1, b: 2, c: 3}
|
480
|
+
# hash.rename_key_unordered!(:b, :middle)
|
481
|
+
# # => {a: 1, c: 3, middle: 2} # Order may differ
|
482
|
+
#
|
483
|
+
def rename_key_unordered!(old_key, new_key)
|
484
|
+
self[new_key] = delete(old_key)
|
485
|
+
self
|
486
|
+
end
|
487
|
+
|
342
488
|
private
|
343
489
|
|
344
490
|
def transform_values_enumerator
|
@@ -3,10 +3,12 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core Module class
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #attr_predicate: Create boolean-style accessor methods
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# require "everythingrb/module"
|
8
11
|
#
|
9
|
-
# @example Creating predicate methods
|
10
12
|
# class User
|
11
13
|
# attr_accessor :admin
|
12
14
|
# attr_predicate :admin
|
@@ -14,7 +16,7 @@
|
|
14
16
|
#
|
15
17
|
# user = User.new
|
16
18
|
# user.admin = true
|
17
|
-
# user.admin?
|
19
|
+
# user.admin? # => true
|
18
20
|
#
|
19
21
|
class Module
|
20
22
|
#
|
@@ -3,12 +3,17 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's OpenStruct class
|
5
5
|
#
|
6
|
-
#
|
7
|
-
# methods
|
6
|
+
# Provides:
|
7
|
+
# - #map, #filter_map: Enumeration methods for OpenStruct entries
|
8
|
+
# - #join_map: Combine filter_map and join operations
|
9
|
+
# - #blank?, #present?: ActiveSupport integrations when available
|
10
|
+
# - #to_deep_h: Recursively convert to hash with all nested objects
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# require "everythingrb/ostruct"
|
8
14
|
#
|
9
|
-
# @example Using enumeration methods
|
10
15
|
# person = OpenStruct.new(name: "Alice", age: 30)
|
11
|
-
# person.map { |k, v| "#{k}
|
16
|
+
# person.map { |k, v| "#{k}: #{v}" } # => ["name: Alice", "age: 30"]
|
12
17
|
#
|
13
18
|
class OpenStruct
|
14
19
|
# ActiveSupport integrations
|
@@ -105,4 +110,20 @@ class OpenStruct
|
|
105
110
|
def to_ostruct
|
106
111
|
self
|
107
112
|
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Recursively converts the OpenStruct and all nested objects to hashes
|
116
|
+
#
|
117
|
+
# @return [Hash] A deeply converted hash of the OpenStruct
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# person = OpenStruct.new(
|
121
|
+
# name: "Alice",
|
122
|
+
# address: OpenStruct.new(city: "New York", country: "USA")
|
123
|
+
# )
|
124
|
+
# person.to_deep_h # => {name: "Alice", address: {city: "New York", country: "USA"}}
|
125
|
+
#
|
126
|
+
def to_deep_h
|
127
|
+
to_h.to_deep_h
|
128
|
+
end
|
108
129
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ostruct"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
#
|
7
|
+
# EverythingRB - Super handy extensions to Ruby's core classes
|
8
|
+
#
|
9
|
+
# This gem enhances Ruby's built-in classes with useful methods that make
|
10
|
+
# your code more expressive and fun to write. Just require "everythingrb"
|
11
|
+
# and all the extensions are automatically available!
|
12
|
+
#
|
13
|
+
# @author Bryan "itsthedevman"
|
14
|
+
# @since 0.1.0
|
15
|
+
#
|
16
|
+
# @example Basic usage
|
17
|
+
# # In your Gemfile
|
18
|
+
# gem "everythingrb"
|
19
|
+
#
|
20
|
+
# # In your code
|
21
|
+
# require "everythingrb"
|
22
|
+
#
|
23
|
+
# # Now you have access to all the extensions!
|
24
|
+
# users = [{name: "Alice"}, {name: "Bob"}]
|
25
|
+
# users.key_map(:name).join(", ") # => "Alice, Bob"
|
26
|
+
#
|
27
|
+
module Everythingrb
|
28
|
+
end
|
29
|
+
|
30
|
+
require_relative "version"
|
@@ -3,14 +3,17 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core String class
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #to_h, #to_a: Convert JSON strings to Hash/Array with error handling
|
8
|
+
# - #to_deep_h: Recursively parse nested JSON strings
|
9
|
+
# - #to_ostruct, #to_istruct, #to_struct: Convert JSON to data structures
|
10
|
+
# - #with_quotes, #in_quotes: Wrap strings in quotes
|
8
11
|
#
|
9
|
-
# @example
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
12
|
+
# @example
|
13
|
+
# require "everythingrb/string"
|
14
|
+
#
|
15
|
+
# '{"user": {"name": "Alice"}}'.to_ostruct.user.name # => "Alice"
|
16
|
+
# "Hello".with_quotes # => "\"Hello\""
|
14
17
|
#
|
15
18
|
class String
|
16
19
|
#
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Extensions to Ruby's core Struct class
|
5
|
+
#
|
6
|
+
# Provides:
|
7
|
+
# - #to_deep_h: Recursively convert to hash with all nested objects
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# require "everythingrb/struct"
|
11
|
+
#
|
12
|
+
# Person = Struct.new(:name, :profile)
|
13
|
+
# person = Person.new("Alice", {roles: ["admin"]})
|
14
|
+
# person.to_deep_h # => {name: "Alice", profile: {roles: ["admin"]}}
|
15
|
+
#
|
16
|
+
class Struct
|
17
|
+
#
|
18
|
+
# Recursively converts the Struct and all nested objects to hashes
|
19
|
+
#
|
20
|
+
# @return [Hash] A deeply converted hash of the Struct
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# Address = Struct.new(:city, :country)
|
24
|
+
# Person = Struct.new(:name, :address)
|
25
|
+
# person = Person.new("Alice", Address.new("New York", "USA"))
|
26
|
+
# person.to_deep_h # => {name: "Alice", address: {city: "New York", country: "USA"}}
|
27
|
+
#
|
28
|
+
def to_deep_h
|
29
|
+
to_h.to_deep_h
|
30
|
+
end
|
31
|
+
end
|
@@ -3,9 +3,12 @@
|
|
3
3
|
#
|
4
4
|
# Extensions to Ruby's core Symbol class
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# Provides:
|
7
|
+
# - #with_quotes, #in_quotes: Wrap symbols in quotes
|
7
8
|
#
|
8
9
|
# @example
|
10
|
+
# require "everythingrb/symbol"
|
11
|
+
#
|
9
12
|
# :hello_world.with_quotes # => :"\"hello_world\""
|
10
13
|
#
|
11
14
|
class Symbol
|
data/lib/everythingrb/version.rb
CHANGED
data/lib/everythingrb.rb
CHANGED
@@ -1,37 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require_relative "everythingrb/version"
|
7
|
-
require_relative "everythingrb/core/array"
|
8
|
-
require_relative "everythingrb/core/enumerable"
|
9
|
-
require_relative "everythingrb/core/hash"
|
10
|
-
require_relative "everythingrb/core/module"
|
11
|
-
require_relative "everythingrb/core/ostruct"
|
12
|
-
require_relative "everythingrb/core/string"
|
13
|
-
require_relative "everythingrb/core/symbol"
|
14
|
-
|
15
|
-
#
|
16
|
-
# EverythingRB - Super handy extensions to Ruby's core classes
|
17
|
-
#
|
18
|
-
# This gem enhances Ruby's built-in classes with useful methods that make
|
19
|
-
# your code more expressive and fun to write. Just require "everythingrb"
|
20
|
-
# and all the extensions are automatically available!
|
21
|
-
#
|
22
|
-
# @author Bryan "itsthedevman"
|
23
|
-
# @since 0.1.0
|
24
|
-
#
|
25
|
-
# @example Basic usage
|
26
|
-
# # In your Gemfile
|
27
|
-
# gem "everythingrb"
|
28
|
-
#
|
29
|
-
# # In your code
|
30
|
-
# require "everythingrb"
|
31
|
-
#
|
32
|
-
# # Now you have access to all the extensions!
|
33
|
-
# users = [{name: "Alice"}, {name: "Bob"}]
|
34
|
-
# users.key_map(:name).join(", ") # => "Alice, Bob"
|
35
|
-
#
|
36
|
-
module Everythingrb
|
37
|
-
end
|
3
|
+
require_relative "everythingrb/prelude"
|
4
|
+
require_relative "everythingrb/all"
|
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.4.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-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ostruct
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2.
|
33
|
+
version: '2.10'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2.
|
40
|
+
version: '2.10'
|
41
41
|
description: EverythingRB extends Ruby core classes with useful methods for combining
|
42
42
|
operations (join_map), converting data structures (to_struct, to_ostruct, to_istruct),
|
43
43
|
and handling JSON with nested parsing support.
|
@@ -57,13 +57,17 @@ files:
|
|
57
57
|
- flake.lock
|
58
58
|
- flake.nix
|
59
59
|
- lib/everythingrb.rb
|
60
|
-
- lib/everythingrb/
|
61
|
-
- lib/everythingrb/
|
62
|
-
- lib/everythingrb/
|
63
|
-
- lib/everythingrb/
|
64
|
-
- lib/everythingrb/
|
65
|
-
- lib/everythingrb/
|
66
|
-
- lib/everythingrb/
|
60
|
+
- lib/everythingrb/all.rb
|
61
|
+
- lib/everythingrb/array.rb
|
62
|
+
- lib/everythingrb/data.rb
|
63
|
+
- lib/everythingrb/enumerable.rb
|
64
|
+
- lib/everythingrb/hash.rb
|
65
|
+
- lib/everythingrb/module.rb
|
66
|
+
- lib/everythingrb/ostruct.rb
|
67
|
+
- lib/everythingrb/prelude.rb
|
68
|
+
- lib/everythingrb/string.rb
|
69
|
+
- lib/everythingrb/struct.rb
|
70
|
+
- lib/everythingrb/symbol.rb
|
67
71
|
- lib/everythingrb/version.rb
|
68
72
|
homepage: https://github.com/itsthedevman/everythingrb
|
69
73
|
licenses:
|