class Hash # Turn 'keys' into :symbols def symbolize_keys inject({}) do |options, (key, value)| options[(key.to_sym rescue key) || key] = value options end end # Merge other into self as a normal merge, with the exception that # when there are duplicate keys and the other.value is an array, # make a flat uniquified array by merging both arrays together # @param other [Hash] the other Hash # @return [Hash] a new Hash def flak_merge(other) d = self.dup other.each do |k,v| if ( d.has_key?(k) && v.kind_of?(Array) ) d[k] = ([ self[k] ] | v.dup ).flatten.uniq else d[k] = v end end d end # Return a value which is an object of value's type. # If key is duplicate in self and value is an array, then merge it # However, if value is not an array, return it, even if self[key] is an array. # We do this to make sure the incoming type takes precedence # same as flak_merge really # @param key [Object] the key # @param value [Object] the value # @return [Object] a new object of the same type as value def flak_merge_key(key,value) if ( self.has_key?(key) && value.kind_of?(Array) ) ([ self[key] ] | value.dup ).flatten.uniq else value end end # Looks for keys that are nested under "os_*" or "configuration_*" keys # or both, i.e. os_* -> configuration_*. # A flattened hash is generated where only agnostic entries, or #entries for the current os and configration are present. # @param configuration [String] the configuration. e.g.'debug' # @param os [String] the os. e.g.'darwin' def flak_flatten(configuration,os) h = Hash.new self.each do |k,v| if ( ! ((k =~/^os_.*/) || (k =~/^configuration_.*/)) ) h[k] = h.flak_merge_key(k,v) else if (k == "os_#{os}" ) v.each do |k1,v1| if (k1 =~ /^configuration_.*/ ) if (k1 == "configuration_#{configuration}" ) v1.each do |k2,v2| h[k2] = h.flak_merge_key(k2,v2) end end else h[k1] = h.flak_merge_key(k1,v1) end end else if (k == "configuration_#{configuration}" ) v.each do |k1,v1| h[k1] = h.flak_merge_key(k1,v1) end end end end end h.symbolize_keys end end