Class: BlueprintConfig::OptionsHash

Inherits:
Hash
  • Object
show all
Defined in:
lib/blueprint_config/options_hash.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, path: nil, source: nil) ⇒ OptionsHash

Returns a new instance of OptionsHash.



9
10
11
12
13
14
15
16
# File 'lib/blueprint_config/options_hash.rb', line 9

def initialize(options = {}, path: nil, source: nil)
  super() # important - brackets needed to create an empty hash
  @__path = path
  @__sources = {}
  options.each do |key, value|
    __set(key, value, source:)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/blueprint_config/options_hash.rb', line 62

def method_missing(name, *args)
  name_string = +name.to_s
  if name_string.chomp!('=')
    self[name_string] = args.first
  else
    questions = name_string.chomp!('?')
    if questions
      self[name_string].present?
    else
      bangs = name_string.chomp!('!')

      if bangs
        self[name_string].presence ||
          raise(KeyError, "Configuration key '#{[@__path, name_string].compact.join('.')}' is not set", caller[1..])
      else
        self[name_string]
      end
    end
  end
end

Instance Attribute Details

#__pathObject

include ActiveSupport::DeepMergeable



7
8
9
# File 'lib/blueprint_config/options_hash.rb', line 7

def __path
  @__path
end

#__sourcesObject

include ActiveSupport::DeepMergeable



7
8
9
# File 'lib/blueprint_config/options_hash.rb', line 7

def __sources
  @__sources
end

Instance Method Details

#[](key) ⇒ Object



18
19
20
# File 'lib/blueprint_config/options_hash.rb', line 18

def [](key)
  super(key.to_sym)
end

#__set(key, value, source: nil) ⇒ Object



31
32
33
34
35
36
# File 'lib/blueprint_config/options_hash.rb', line 31

def __set(key, value, source: nil)
  value = self.class.new(value, path: [@__path, key].compact.join('.'), source:) if value.is_a?(Hash)
  value = OptionsArray.new(value, path: [@__path, key].compact.join('.'), source:) if value.is_a?(Array)
  @__sources[key] = source
  self[key.to_sym] = value
end

#deep_merge(other, &block) ⇒ Object

deep_merge methods copied from ActiveSupport to avoid extra dependency



90
91
92
# File 'lib/blueprint_config/options_hash.rb', line 90

def deep_merge(other, &block)
  dup.deep_merge!(other, &block)
end

#deep_merge!(other, &block) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/blueprint_config/options_hash.rb', line 94

def deep_merge!(other, &block)
  merge!(other) do |key, this_val, other_val|
    if this_val.is_a?(BlueprintConfig::OptionsHash) && this_val.deep_merge?(other_val)
      this_val.deep_merge(other_val, &block)
    elsif this_val.is_a?(BlueprintConfig::OptionsArray) && other_val.is_a?(BlueprintConfig::OptionsArray)
      this_val.__assign(other_val, &block)
    elsif block_given?
      block.call(key, this_val, other_val)
    else
      other_val
    end
  end
end

#deep_merge?(other) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/blueprint_config/options_hash.rb', line 108

def deep_merge?(other)
  other.is_a?(self.class)
end

#dig(key, *identifiers) ⇒ Object



22
23
24
# File 'lib/blueprint_config/options_hash.rb', line 22

def dig(key, *identifiers)
  super(key.to_sym, *identifiers)
end

#dig!(*args, &block) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'lib/blueprint_config/options_hash.rb', line 51

def dig!(*args, &block)
  leading = args.shift
  if args.empty?
    fetch(leading, &block)
  else
    fetch(leading, &block).dig!(*args, &block)
  end
rescue KeyError => e
  raise e, e.message, caller[1..], cause: nil
end

#fetch(key, *args, &block) ⇒ Object



83
84
85
86
87
# File 'lib/blueprint_config/options_hash.rb', line 83

def fetch(key, *args, &block)
  super(key.to_sym, *args, &block)
rescue KeyError
  raise KeyError, "Configuration key '#{[@__path, key].compact.join('.')}' is not set", caller[1..], cause: nil
end

#merge!(other, &block) ⇒ Object



26
27
28
29
# File 'lib/blueprint_config/options_hash.rb', line 26

def merge!(other, &block)
  @__sources.reverse_merge!(other.__sources) if other.is_a?(OptionsHash)
  super
end

#source(*args) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/blueprint_config/options_hash.rb', line 38

def source(*args)
  key = args.shift
  if args.empty?
    "#{@__sources[key]} #{[@__path, key].compact.join('.')}"
  else
    unless key?(key)
      raise KeyError, "Configuration key '#{[@__path, key].compact.join('.')}' is not set", caller[1..], cause: nil
    end

    self[key].source(*args)
  end
end