Class: Hash
- Inherits:
-
Object
- Object
- Hash
- Defined in:
- lib/everythingrb/core/hash.rb
Overview
Extensions to Ruby’s core Hash class
These additions make working with hashes more convenient by adding conversion methods to different data structures and string formatting helpers.
Constant Summary collapse
- EMPTY_STRUCT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
A minimal empty struct for Ruby 3.2+ compatibility
Ruby 3.2 enforces stricter argument handling for Struct. This means trying to create a Struct from an empty Hash will result in an ArgumentError being raised. This is trying to keep a consistent experience with that version and newer versions.
Struct.new(:_).new(nil)
Class Method Summary collapse
-
.new_nested_hash ⇒ Hash
Creates a new Hash that automatically initializes missing keys with nested hashes.
Instance Method Summary collapse
-
#deep_freeze ⇒ self
Recursively freezes self and all of its values.
-
#join_map(join_with = "") {|key, value| ... } ⇒ String
Combines filter_map and join operations.
-
#og_transform_values ⇒ Object
Allows calling original method.
-
#og_transform_values! ⇒ Object
Allows calling original method.
-
#to_deep_h ⇒ Hash
Recursively converts all values that respond to #to_h.
-
#to_istruct ⇒ Data
Converts hash to an immutable Data structure.
-
#to_ostruct ⇒ OpenStruct
Converts hash to an OpenStruct recursively.
-
#to_struct ⇒ Struct
Converts hash to a Struct recursively.
-
#transform_values {|value| ... } ⇒ Hash, Enumerator
Transforms hash values while allowing access to keys via the chainable with_key method.
-
#transform_values! {|value| ... } ⇒ self, Enumerator
Transforms hash values in place while allowing access to keys via the chainable with_key method.
-
#value_where {|key, value| ... } ⇒ Object, ...
Returns the first value where the key-value pair satisfies the given condition.
-
#values_where {|key, value| ... } ⇒ Array, Enumerator
Returns all values where the key-value pairs satisfy the given condition.
Class Method Details
.new_nested_hash ⇒ Hash
While extremely convenient, be cautious with very deep structures as this creates new hashes on demand for any key access
Creates a new Hash that automatically initializes missing keys with nested hashes
This method creates a hash where any missing key access will automatically create another nested hash with the same behavior, allowing for unlimited nesting depth without explicit initialization.
54 55 56 |
# File 'lib/everythingrb/core/hash.rb', line 54 def self.new_nested_hash new { |hash, key| hash[key] = new_nested_hash } end |
Instance Method Details
#deep_freeze ⇒ self
CAUTION: Be careful when freezing collections that contain class objects or singleton instances - this will freeze those classes/objects globally! Only use deep_freeze on pure data structures you want to make immutable.
Recursively freezes self and all of its values
223 224 225 226 |
# File 'lib/everythingrb/core/hash.rb', line 223 def deep_freeze each_value { |v| v.respond_to?(:deep_freeze) ? v.deep_freeze : v.freeze } freeze end |
#join_map(join_with = "") {|key, value| ... } ⇒ String
Combines filter_map and join operations
77 78 79 80 81 |
# File 'lib/everythingrb/core/hash.rb', line 77 def join_map(join_with = "", &block) block = ->(kv_pair) { kv_pair.compact } if block.nil? filter_map(&block).join(join_with) end |
#og_transform_values ⇒ Object
Allows calling original method. See below
229 |
# File 'lib/everythingrb/core/hash.rb', line 229 alias_method :og_transform_values, :transform_values |
#og_transform_values! ⇒ Object
Allows calling original method. See below
232 |
# File 'lib/everythingrb/core/hash.rb', line 232 alias_method :og_transform_values!, :transform_values! |
#to_deep_h ⇒ Hash
Recursively converts all values that respond to #to_h
Similar to #to_h but recursively traverses the Hash structure and calls #to_h on any object that responds to it. Useful for normalizing nested data structures and parsing nested JSON.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/everythingrb/core/hash.rb', line 114 def to_deep_h transform_values do |value| case value when Hash value.to_deep_h when Array value.to_deep_h when String # If the string is not valid JSON, #to_deep_h will return `nil` value.to_deep_h || value else value.respond_to?(:to_h) ? value.to_h : value end end end |
#to_istruct ⇒ Data
Converts hash to an immutable Data structure
141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/everythingrb/core/hash.rb', line 141 def to_istruct recurse = lambda do |input| case input when Hash input.to_istruct when Array input.map(&recurse) else input end end Data.define(*keys.map(&:to_sym)).new(*values.map { |value| recurse.call(value) }) end |
#to_ostruct ⇒ OpenStruct
Converts hash to an OpenStruct recursively
195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/everythingrb/core/hash.rb', line 195 def to_ostruct recurse = lambda do |value| case value when Hash value.to_ostruct when Array value.map(&recurse) else value end end OpenStruct.new(**transform_values { |value| recurse.call(value) }) end |
#to_struct ⇒ Struct
Converts hash to a Struct recursively
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/everythingrb/core/hash.rb', line 167 def to_struct # For Ruby 3.2, it raises if you attempt to create a Struct with no keys return EMPTY_STRUCT if RUBY_VERSION.start_with?("3.2") && empty? recurse = lambda do |value| case value when Hash value.to_struct when Array value.map(&recurse) else value end end Struct.new(*keys.map(&:to_sym)).new(*values.map { |value| recurse.call(value) }) end |
#transform_values {|value| ... } ⇒ Hash, Enumerator
Transforms hash values while allowing access to keys via the chainable with_key method
This method either performs a standard transform_values operation if a block is given, or returns an enumerator with a with_key method that passes both the key and value to the block.
255 256 257 258 259 |
# File 'lib/everythingrb/core/hash.rb', line 255 def transform_values(&block) return transform_values_enumerator if block.nil? og_transform_values(&block) end |
#transform_values! {|value| ... } ⇒ self, Enumerator
Transforms hash values in place while allowing access to keys via the chainable with_key method
This method either performs a standard transform_values! operation if a block is given, or returns an enumerator with a with_key method that passes both the key and value to the block, updating the hash in place.
285 286 287 288 289 |
# File 'lib/everythingrb/core/hash.rb', line 285 def transform_values!(&block) return transform_values_bang_enumerator if block.nil? og_transform_values!(&block) end |
#value_where {|key, value| ... } ⇒ Object, ...
Returns the first value where the key-value pair satisfies the given condition
310 311 312 313 314 |
# File 'lib/everythingrb/core/hash.rb', line 310 def value_where(&block) return to_enum(:value_where) if block.nil? find(&block).last end |
#values_where {|key, value| ... } ⇒ Array, Enumerator
Returns all values where the key-value pairs satisfy the given condition
336 337 338 339 340 |
# File 'lib/everythingrb/core/hash.rb', line 336 def values_where(&block) return to_enum(:values_where) if block.nil? select(&block).values end |