lib/skippy/config.rb in skippy-0.2.0.a vs lib/skippy/config.rb in skippy-0.3.0.a

- old
+ new

@@ -3,38 +3,24 @@ require 'skippy/error' class Skippy::Config < Hash - attr_accessor :path + attr_reader :path class MissingPathError < Skippy::Error; end def self.load(path, defaults = {}) if path.exist? json = File.read(path) config = JSON.parse(json, symbolize_names: true, - object_class: self - ) + object_class: self) else - config = self.new + config = new end - # Need to merge nested defaults. - config.merge!(defaults) { |_key, value, default| - if value.is_a?(Hash) && default.is_a?(Hash) - # Deep merge in order to merge nested hashes. - # Note: This currently doesn't merge arrays. - # http://stackoverflow.com/a/9381776/486990 - merger = proc { |_k, v1, v2| - Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 - } - default.merge(value, &merger) - else - value || default - end - } + config.merge_defaults(defaults) config.path = path config end def get(key_path, default = nil) @@ -75,24 +61,43 @@ def update(hash) if hash.keys.first.is_a?(String) update_from_key_paths(hash) else - update_from_hash(hash) + deep_merge!(hash) end self end def inspect "#{super}:#{self.class.name}" end + # @param [Hash] defaults + def merge_defaults(defaults) + merge!(defaults) { |_key, value, default| + if value.is_a?(Hash) && default.is_a?(Hash) + # Deep merge in order to merge nested hashes. + # Note: This currently doesn't merge arrays. + # http://stackoverflow.com/a/9381776/486990 + merger = proc { |_k, v1, v2| + v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 + } + default.merge(value, &merger) + else + # TODO(thomthom): Should `merger` include this logic? + value || default + end + } + end + private - def update_from_hash(hash) + # @param [Hash] hash + def deep_merge!(hash) merger = proc { |_key, v1, v2| - Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 + v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 } merge!(hash, &merger) end def update_from_key_paths(key_paths) @@ -103,10 +108,10 @@ def key_parts(key_path) if key_path.is_a?(Symbol) [key_path] else - key_path.split('/').map { |key| key.intern } + key_path.split('/').map(&:intern) end end def get_item(key_path) parts = key_parts(key_path)