Class: Configoro::Hash

Inherits:
HashWithIndifferentAccess show all
Defined in:
lib/configoro/hash.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from HashWithIndifferentAccess

#deep_merge

Constructor Details

#initialize(hsh = {}) ⇒ Hash

Returns a new instance of Hash.



5
6
7
8
9
10
11
12
# File 'lib/configoro/hash.rb', line 5

def initialize(hsh={})
  if hsh.kind_of?(::Hash)
    super()
    update hsh
  else
    super
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object

To optimize access, we create a getter method every time we encounter a key that exists in the hash. If the key is later deleted, the method will be removed.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/configoro/hash.rb', line 74

def method_missing(meth, *args)
  if include?(meth.to_s)
    if args.empty?
      create_getter meth
    else
      raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
    end
  elsif meth.to_s =~/^(.+)\?$/ && include?((root_meth = Regexp.last_match(1)))
    if args.empty?
      !!create_getter(root_meth) #TODO duplication of logic
    else
      raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
    end
  else
    super
  end
end

Class Method Details

.new_from_hash_copying_default(hash) ⇒ Object



116
117
118
119
120
# File 'lib/configoro/hash.rb', line 116

def self.new_from_hash_copying_default(hash)
  Configoro::Hash.new(hash).tap do |new_hash|
    new_hash.default = hash.default
  end
end

Instance Method Details

#<<(hash) ⇒ Configoro::Hash #<<(path) ⇒ Configoro::Hash Also known as: push

Deep-merges additional hash entries into this hash.

Overloads:

  • #<<(hash) ⇒ Configoro::Hash

    Adds the entries from another hash.

    Parameters:

    • hash (::Hash)

      The additional keys to add.

  • #<<(path) ⇒ Configoro::Hash

    Adds the entries from a YAML file. The entries will be added under a sub-hash named after the YAML file’s name.

    Parameters:

    • path (String)

      The path to a YAML file ending in “.yml”.

    Raises:

    • (ArgumentError)

      If the filename does not end in “.yml”.

Returns:



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/configoro/hash.rb', line 26

def <<(hsh_or_path)
  case hsh_or_path
    when String
      raise ArgumentError, "Only files ending in .yml can be added" unless File.extname(hsh_or_path) == '.yml'
      return self unless File.exist?(hsh_or_path)

      data = load_preprocessed_yaml(hsh_or_path)
      deep_merge! File.basename(hsh_or_path, ".yml") => data
    when ::Hash
      deep_merge! hsh_or_path
  end
end

#deep_merge!(other_hash) ⇒ Configoro::Hash

Recursively merges this hash with another hash. All nested hashes are forced to be ‘Configoro::Hash` instances.

Parameters:

  • other_hash (::Hash)

    The hash to merge into this one.

Returns:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/configoro/hash.rb', line 52

def deep_merge!(other_hash)
  other_hash.each_pair do |k, v|
    tv      = self[k]
    self[k] = if v.kind_of?(::Hash)
                if tv.kind_of?(::Hash)
                  Configoro::Hash.new(tv).deep_merge!(v)
                else
                  Configoro::Hash.new(v)
                end
              else
                v
              end
  end
  self
end

#dupObject



42
43
44
# File 'lib/configoro/hash.rb', line 42

def dup
  Hash.new(self)
end

#inspectObject



100
101
102
# File 'lib/configoro/hash.rb', line 100

def inspect
  "#{to_hash.inspect}:#{self.class}"
end

#respond_to_missing?(meth, *args) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
96
97
# File 'lib/configoro/hash.rb', line 93

def respond_to_missing?(meth, *args)
  include?(meth.to_s) ||
      (meth.to_s =~ /^(.+)\?$/ && include?(Regexp.last_match(1))) ||
      super(meth, *args)
end

#to_symbolized_hashObject



104
105
106
107
108
109
110
111
112
113
# File 'lib/configoro/hash.rb', line 104

def to_symbolized_hash
  each_with_object({}) do |(key, value), hsh|
    hsh[key.to_sym] = case value
                        when Configoro::Hash
                          value.to_symbolized_hash
                        else
                          value
                      end
  end
end