Class: Contours::BlendedHash
- Inherits:
-
Hash
- Object
- Hash
- Contours::BlendedHash
- Defined in:
- lib/contours/blended_hash.rb
Overview
BlendedHash is a utility class that allows you to merge two hashes. It may be used to specify how to combine values that are specified more than once. For example, if you have a BlendedHash like this:
class CssConfig < BlendedHash
@blended_keys = %i[class]
def blend_class(original, extras)
[original, extras].flatten.compact.uniq.join(" ")
end
end
CssConfig.new({class: "foo"})
And you merge it with another hash like this:
CssConfig.new({class: "foo"}).merge({class: "bar"})
The result will be:
{
class: "foo bar"
}
See the source of this #name class for more details.
Class Attribute Summary collapse
-
.blended_keys ⇒ Object
readonly
Returns the value of attribute blended_keys.
Class Method Summary collapse
-
.blend(key, with: nil, &block) ⇒ Object
Define a method that will be used to blend the value of a key.
-
.init(initial_hash) ⇒ Object
Ensure that the initial hash is a BlendedHash.
Instance Method Summary collapse
-
#[] ⇒ Object
Ensure that the return value of these methods is a BlendedHash.
-
#blend(original, extra) ⇒ Object
Default implementation of the blend method.
- #blended_keys ⇒ Object
- #dig ⇒ Object
- #fetch ⇒ Object
-
#merge(overrides) ⇒ BlendedHash
Recursively check for keys that are specified as blended and apply the blend method to them or execute the blend_#key method if it exists to set the new value.
- #to_hash ⇒ Object
Class Attribute Details
.blended_keys ⇒ Object (readonly)
Returns the value of attribute blended_keys.
145 146 147 |
# File 'lib/contours/blended_hash.rb', line 145 def blended_keys @blended_keys end |
Class Method Details
.blend(key, with: nil, &block) ⇒ Object
Define a method that will be used to blend the value of a key. The method name will be “blend_#key”. If a block is given, it will be used as the implementation of the method. Otherwise, the default implementation will be used where the value of the with argument is expected to receive ‘init’ with the original value and then ‘merge’ with the extras value.
68 69 70 71 72 73 74 75 76 |
# File 'lib/contours/blended_hash.rb', line 68 def self.blend(key, with: nil, &block) if block define_method(:"blend_#{key}", &block) else define_method(:"blend_#{key}") do |original, extras| with.init(original).merge(extras) end end end |
.init(initial_hash) ⇒ Object
Ensure that the initial hash is a BlendedHash
31 32 33 34 35 36 37 |
# File 'lib/contours/blended_hash.rb', line 31 def self.init(initial_hash) if initial_hash.is_a?(BlendedHash) initial_hash else new({}).merge(initial_hash) end end |
Instance Method Details
#[] ⇒ Object
Ensure that the return value of these methods is a BlendedHash
114 115 116 117 118 119 120 121 |
# File 'lib/contours/blended_hash.rb', line 114 def [](...) super_result = super if super_result.is_a?(Hash) self.class.init(super_result) else super_result end end |
#blend(original, extra) ⇒ Object
Default implementation of the blend method. Override this in subclasses with a custom blend_#key method to customize the blending behavior for a specific key.
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/contours/blended_hash.rb', line 153 def blend(original, extra) case original when BlendedHash, Hash self.class.init(original).merge(extra) when Array [original, extra].flatten.compact.uniq else extra end end |
#blended_keys ⇒ Object
147 |
# File 'lib/contours/blended_hash.rb', line 147 def blended_keys = self.class.blended_keys |
#dig ⇒ Object
132 133 134 135 136 137 138 139 |
# File 'lib/contours/blended_hash.rb', line 132 def dig(...) super_result = super if super_result.is_a?(Hash) self.class.init(super_result) else super_result end end |
#fetch ⇒ Object
123 124 125 126 127 128 129 130 |
# File 'lib/contours/blended_hash.rb', line 123 def fetch(...) super_result = super if super_result.is_a?(Hash) self.class.init(super_result) else super_result end end |
#merge(overrides) ⇒ BlendedHash
Recursively check for keys that are specified as blended and apply the blend method to them or execute the blend_#key method if it exists to set the new value.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/contours/blended_hash.rb', line 97 def merge(overrides) return self if overrides.nil? || overrides.empty? self.class.new(overrides.each_with_object(to_hash.dup) do |(key, value), hash| hash[key] = if blended_keys.include?(key) if respond_to?(:"blend_#{key}") send(:"blend_#{key}", hash[key], value) else blend(hash[key], value) end else value end hash end) end |
#to_hash ⇒ Object
164 165 166 |
# File 'lib/contours/blended_hash.rb', line 164 def to_hash deep_stringify_structured_strings(__getobj__) end |