sealink/ruby_core_extensions

View on GitHub
lib/ruby_core_extensions/recursive/hash.rb

Summary

Maintainability
A
45 mins
Test Coverage
class Hash
  def recursive_blank?
    each do |k, v|
      if v.respond_to?(:recursive_blank?)
        return false unless v.recursive_blank?
      else
        return false unless v.blank?
      end
    end
    true
  end

  def convert
    self
  end

  def convert_keys(&converter)
    inject({}) do |hash, (key, value)|
      hash[converter.call(key)] = value
      hash
    end
  end

  def convert_values(*keys, &converter)
    inject(clone) do |hash, (key, value)|
      hash[key] = value.convert(&converter) if keys.blank? || keys.include?(key)
      hash
    end
  end

  def convert_keys_recursively(&converter)
    Hash[map do |key, value|
          k = converter.call(key)
          v = value.convert_keys_recursively(&converter)
          [k, v]
        end]
  end

  def convert_values_recursively(&converter)
    inject({}) do |hash, (key, value)|
      hash[key] = value.convert_values_recursively(&converter)
      hash
    end
  end

  def symbolize_keys_recursively
    Hash[map do |key, value|
          k = key.is_a?(String) ? key.to_sym : key
          v = value.symbolize_keys_recursively
          [k, v]
        end]
  end

  def stringify_values_recursively
    inject({}) do |options, (key, value)|
      options[key] = value.stringify_values_recursively
      options
    end
  end

  def make_indifferent_access_recursively
    HashWithIndifferentAccess.new(inject({}) do |options, (key, value)|
        options[key] = value.make_indifferent_access_recursively
        options
      end)
  end

  def deep_dup
    duplicate = self.dup
    duplicate.each_pair do |k, v|
      tv = duplicate[k]
      duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
    end
    duplicate
  end

  def recursively(&block)
    each do |key, value|
      block.call(key, value)
      value.recursively(&block) if value.respond_to?(:recursively)
    end
  end
end