Module: EasyFormat
- Defined in:
- lib/easy_format/date_time.rb,
lib/easy_format/validation.rb,
lib/easy_format/file_system.rb,
lib/easy_format/data_type_helper.rb
Defined Under Namespace
Modules: DateTime, Directory, File, Hash
Class Method Summary collapse
-
.deep_diff(base, comparison) ⇒ Object
Deep diff two structures For a hash, returns keys found in both hashes where the values don’t match.
-
.deep_diff_by_key(base, comparison, keep_values: false) ⇒ Object
Identifies what keys in the comparison hash are missing from base hash.
-
.deep_merge(base, override, boolean_or: false, left_outer_join_depth: 0) ⇒ Object
Deep merge two structures boolean_or: use a boolean || operator on the base and override if they are not a Hash or Array Left outer join: Only merge keys that already exist in the base.
-
.deep_reject(hash, &block) ⇒ Object
Reject hash keys however deep they are.
-
.deep_reject_by_hash(base, comparison) ⇒ Object
Deep diff two Hashes Remove any keys in the first hash also contained in the second hash If a key exists in the base, but NOT the comparison, it is kept.
- .reject_keys_with_nil_values(base) ⇒ Object
-
.validate_parameters(method, method_binding, optional_parameters = []) ⇒ Object
Optional parameters should be an array of symbols or strings rubocop:disable Security/Eval.
Class Method Details
.deep_diff(base, comparison) ⇒ Object
Deep diff two structures For a hash, returns keys found in both hashes where the values don’t match. If a key exists in the base, but NOT the comparison, it is NOT considered a difference so that it can be a one way comparison. For an array, returns an array with values found in the comparison array but not in the base array.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/easy_format/data_type_helper.rb', line 116 def deep_diff(base, comparison) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) if base.nil? # if base is nil, entire comparison object is different return comparison.is_a?(Hash) ? comparison.dup : comparison end case comparison when nil {} when ::Hash differing_values = {} base = base.dup comparison.each do |src_key, src_value| difference = deep_diff(base[src_key], src_value) differing_values[src_key] = difference unless difference == :no_diff end differing_values.reject { |_k, v| v.is_a?(::Hash) && v.empty? } when ::Array difference = comparison - base difference.empty? ? :no_diff : difference else base == comparison ? :no_diff : comparison end end |
.deep_diff_by_key(base, comparison, keep_values: false) ⇒ Object
Identifies what keys in the comparison hash are missing from base hash. Optionally keep the values from the comparison hash, otherwise assigns the missing keys a value of :missing_key
99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/easy_format/data_type_helper.rb', line 99 def deep_diff_by_key(base, comparison, keep_values: false) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) missing_keys = {} if comparison.is_a?(::Hash) compared_keys = base.is_a?(::Hash) ? comparison.keys - base.keys : comparison.keys # Determine what keys the comparison has that the base doesn't compared_keys.each { |k| missing_keys[k] = keep_values ? comparison[k] : :missing_key } # Save the missing keys comparison.each do |k, v| missing_keys[k] = deep_diff_by_key(base[k], v, keep_values: keep_values) if v.is_a?(::Hash) # Recurse to find more missing keys if the hash goes deeper end end missing_keys.reject { |_k, v| v.is_a?(::Hash) && v.empty? } # Remove any empty hashes as there were no missing keys in them end |
.deep_merge(base, override, boolean_or: false, left_outer_join_depth: 0) ⇒ Object
Deep merge two structures
boolean_or: use a boolean || operator on the base and override if they are not a Hash or Array
Left outer join: Only merge keys that already exist in the base
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/easy_format/data_type_helper.rb', line 68 def deep_merge(base, override, boolean_or: false, left_outer_join_depth: 0) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) left_outer_join_depth -= 1 # decrement left_outer_join_depth for recursion if base.nil? return nil if left_outer_join_depth >= 0 return override.is_a?(Hash) ? override.dup : override end case override when nil base = base.dup if base.is_a?(Hash) # duplicate hash to avoid modification by reference issues base # if override doesn't exist, simply return the existing value when ::Hash base = base.dup override.each do |src_key, src_value| next if base[src_key].nil? && left_outer_join_depth >= 0 # if this is a left outer join and the key does not exist in the base, skip it base[src_key] = base[src_key] ? deep_merge(base[src_key], src_value, boolean_or: boolean_or, left_outer_join_depth: left_outer_join_depth) : src_value # Recurse if both are Hash end base when ::Array base |= override base when ::String, ::Integer, ::Time, ::TrueClass, ::FalseClass boolean_or ? base || override : override else throw "Implementation for deep merge of type #{override.class} is missing." end end |
.deep_reject(hash, &block) ⇒ Object
Reject hash keys however deep they are. Provide a block and if it evaluates to true for a given key/value pair, it will be rejected.
142 143 144 145 146 147 148 |
# File 'lib/easy_format/data_type_helper.rb', line 142 def deep_reject(hash, &block) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) hash.each_with_object({}) do |(k, v), h| next if yield(k, v) # reject the current key/value pair by skipping it if the block given evaluates to true h[k] = v.is_a?(::Hash) ? deep_reject(v, &block) : v # recursively go up the hash tree or keep the value if it's not a hash. end end |
.deep_reject_by_hash(base, comparison) ⇒ Object
Deep diff two Hashes Remove any keys in the first hash also contained in the second hash If a key exists in the base, but NOT the comparison, it is kept.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/easy_format/data_type_helper.rb', line 153 def deep_reject_by_hash(base, comparison) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) return nil if base.nil? case comparison when ::Hash return base unless base.is_a?(::Hash) # if base is not a hash but the comparison is, return the base base = base.dup comparison.each do |src_key, src_value| base[src_key] = deep_reject_by_hash(base[src_key], src_value) # recurse to the leaf base[src_key] = nil if base[src_key].is_a?(::Hash) && base[src_key].empty? # set leaves to nil if they are empty hashes end base.reject { |_k, v| v.nil? } # reject any leaves that were set to nil else # rubocop:disable Style/EmptyElse - for clarity nil # drop the value if we have reached a leaf in the comparison hash end end |
.reject_keys_with_nil_values(base) ⇒ Object
171 172 173 174 |
# File 'lib/easy_format/data_type_helper.rb', line 171 def reject_keys_with_nil_values(base) EasyFormat::Hash.log_deprecation('EasyFormat', __method__) deep_reject(base) { |_k, v| v.nil? } end |
.validate_parameters(method, method_binding, optional_parameters = []) ⇒ Object
Optional parameters should be an array of symbols or strings rubocop:disable Security/Eval
6 7 8 9 10 11 12 13 |
# File 'lib/easy_format/validation.rb', line 6 def validate_parameters(method, method_binding, optional_parameters = []) method.parameters.each do |parameter| parameter_name = parameter.last.to_s next if optional_parameters.any? { |o| o.to_s.casecmp(parameter_name) == 0 } parameter_value = eval(parameter_name, method_binding) raise "#{parameter_name} is a required parameter for #{caller[2][/`.*'/][1..-2]}!" if parameter_value.nil? || (parameter_value.respond_to?(:empty?) && parameter_value.empty?) end end |