Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/rconfig/core_ext/hash.rb

Overview

source: rubyforge.org/projects/facets/ version: 1.7.46 license: Ruby License NOTE: remove this method if the Facets gem is installed. BUG: weave is destructive to values in the source hash that are arrays!

(this is acceptable for RConfig's use as the basis for weave!)

Instance Method Summary collapse

Instance Method Details

#weave(other_hash, clobber = false) ⇒ Object

Weaves the contents of two hashes producing a new hash.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
# File 'lib/rconfig/core_ext/hash.rb', line 14

def weave(other_hash, clobber=false)
  return self unless other_hash
  unless other_hash.kind_of?(Hash)
    raise ArgumentError, "RConfig: (Hash#weave) expected <Hash>, but was <#{other_hash.class}>"
  end

  self_dup = self.dup # self.clone does not remove freeze!

  other_hash.each { |key, other_node|

    self_dup[key] =

        if self_node = self_dup[key]

          case self_node
            when Hash

              # hash1, hash2 => hash3 (recursive +)
              if other_node.is_a?(Hash)

                self_node.weave(other_node, clobber)

                # hash, array => error (Can't weave'em, must clobber.)
              elsif other_node.is_a?(Array) && !clobber

                raise(ArgumentError, "RConfig: (Hash#weave) Can't weave Hash and Array")

                # hash, array => hash[key] = array
                # hash, value => hash[key] = value
              else
                other_node
              end

            when Array

              # array, hash => array << hash
              # array1, array2 => array1 + array2
              # array, value => array << value
              unless clobber
                case other_node
                  when Hash
                    self_node << other_node
                  when Array
                    self_node + other_node
                  else
                    self_node << other_node
                end

                # array, hash => hash
                # array1, array2 => array2
                # array, value => value
              else
                other_node
              end

            else

              # value, array => array.unshift(value)
              if other_node.is_a?(Array) && !clobber
                other_node.unshift(self_node)

                # value1, value2 => value2
              else
                other_node
              end

          end # case self_node

          # Target hash didn't have a node matching the key,
          # so just add it from the source hash.
          # !self_dup.has_key?(key) => self_dup.add(key, other_node)
        else
          other_node
        end

  } # other_hash.each

  self_dup # return new weaved hash
end

#weave!(other_hash, clobber = false) ⇒ Object

Same as self.weave(other_hash, dont_clobber) except that it weaves other hash to itself, rather than create a new hash.



97
98
99
100
# File 'lib/rconfig/core_ext/hash.rb', line 97

def weave!(other_hash, clobber=false)
  weaved_hash = self.weave(other_hash, clobber)
  self.merge!(weaved_hash)
end