lib/nugrant/bag.rb in nugrant-1.0.1 vs lib/nugrant/bag.rb in nugrant-1.1.0
- old
+ new
@@ -1,44 +1,96 @@
module Nugrant
class Bag
- def initialize(hash)
- @bag = recompute(hash)
+ attr_reader :__elements
+
+ def initialize(elements = nil)
+ if elements.kind_of?(Bag)
+ @__elements = elements
+ end
+
+ __recompute(elements)
end
- def recompute(hash)
- @bag = {}
- return @bag if hash == nil
+ def [](key)
+ return __fetch(key)
+ end
- hash.each do |key, value|
- if not value.is_a?(Hash)
- @bag[key] = value
+ def method_missing(method, *args, &block)
+ return __fetch(method.to_s)
+ end
+
+ def has?(key)
+ return @__elements.has_key?(key)
+ end
+
+ def empty?()
+ @__elements.size() <= 0
+ end
+
+ ##
+ # This method always perform a deep merge and will deep merge
+ # array scalar values only. This means that we do not merge
+ # within array themselves.
+ #
+ def __merge!(elements)
+ bag = elements.kind_of?(Bag) ? elements : Bag.new(elements)
+ return if bag.empty?()
+
+ bag.each do |key, value|
+ if has?(key)
+ current = @__elements[key]
+ if current.kind_of?(Bag) and value.kind_of?(Bag)
+ current.__merge!(value)
+ elsif current.kind_of?(Array) and value.kind_of?(Array)
+ @__elements[key] = current | value
+ else
+ @__elements[key] = value
+ end
+
next
end
- # It is a hash, transform it into a bag
- @bag[key] = Nugrant::Bag.new(value)
+ @__elements[key] = value
end
-
- return @bag
end
- def [](key)
- return fetch(key)
+ def each()
+ @__elements.each do |key, value|
+ yield key, value
+ end
end
- def method_missing(method, *args, &block)
- return fetch(method.to_s)
+ def __to_hash()
+ return {} if empty?()
+
+ hash = {}
+ each do |key, value|
+ hash[key] = value.kind_of?(Bag) ? value.__to_hash() : value
+ end
+
+ return hash
end
- def has_key?(key)
- return @bag.has_key?(key)
+ def __recompute(hash = nil)
+ @__elements = {}
+ return if hash == nil or not hash.kind_of?(Hash)
+
+ hash.each do |key, value|
+ if not value.kind_of?(Hash)
+ @__elements[key] = value
+ next
+ end
+
+ # It is a hash, transform it into a bag
+ @__elements[key] = Bag.new(value)
+ end
end
- def fetch(key)
- if not has_key?(key)
+ def __fetch(key)
+ if not has?(key)
raise KeyError, "Undefined parameter '#{key}'"
end
- return @bag[key]
+ return @__elements[key]
end
end
end