Class: LayeredHash
Instance Method Summary collapse
-
#[](key) ⇒ Object
Retrieves the value of a key from the current layer using hash notation.
-
#[]=(key, value) ⇒ Object
Sets a key-value pair in the current layer using hash notation.
- #fetch(key, *args) ⇒ Object
-
#get(key) ⇒ Object
Retrieves the value of a key from the highest priority layer that has a value.
-
#get_from_layer(layer, key) ⇒ Object
Retrieves the value of a key from the specified layer.
-
#initialize(table = {}, layers: %i[main])) ⇒ LayeredHash
constructor
A new instance of LayeredHash.
- #merge(*args) ⇒ Object
- #respond_to_missing?(method_name, include_private = false) ⇒ Boolean
-
#set(layer, key, value) ⇒ Object
Sets a key-value pair in the specified layer.
-
#set_current_layer(layer) ⇒ Object
Sets the current layer for use with hash notation ([]).
- #to_h ⇒ Object
Constructor Details
#initialize(table = {}, layers: %i[main])) ⇒ LayeredHash
Returns a new instance of LayeredHash.
7 8 9 10 11 |
# File 'lib/layered_hash.rb', line 7 def initialize(table = {}, layers: %i[main]) @layers = layers.map { |layer| [layer, {}] }.to_h @current_layer = layers.first @layers[@current_layer] = table end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object (private)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/layered_hash.rb', line 15 def method_missing(method, *args, &block) method_name = method.to_s if @layers.respond_to?(method_name) @layers.send(method_name, *args, &block) elsif method_name[-1] == '=' @layers[method_name.chop.to_sym] = args[0] elsif @layers.respond_to?(method_name) @layers.send(method_name, *args) else @layers[method_name.to_sym] end rescue StandardError => err warn("ERROR ** LayeredHash.method_missing(method: #{method_name}," \ " *args: #{args.inspect}, &block)") warn err.inspect warn(caller[0..4]) raise err end |
Instance Method Details
#[](key) ⇒ Object
Retrieves the value of a key from the current layer using hash notation
37 38 39 40 41 |
# File 'lib/layered_hash.rb', line 37 def [](key) raise "Current layer not set" unless @current_layer get_from_layer(@current_layer, key) end |
#[]=(key, value) ⇒ Object
Sets a key-value pair in the current layer using hash notation
44 45 46 47 48 |
# File 'lib/layered_hash.rb', line 44 def []=(key, value) raise "Current layer not set" unless @current_layer set(@current_layer, key, value) end |
#fetch(key, *args) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/layered_hash.rb', line 50 def fetch(key, *args) key_sym = key.to_sym if respond_to?("get_#{key}") send("get_#{key}") # elsif @table.key?(key_sym) elsif @layers[@current_layer].key?(key_sym) # @table[key_sym] @layers[@current_layer][key_sym] elsif block_given? yield key_sym elsif args.count.positive? args.first else binding.irb raise KeyError, "key not found: #{key}" end.tap { |ret| pp([__LINE__, "Poly.fetch #{key} #{args}", '->', ret]) if $pd } end |
#get(key) ⇒ Object
Retrieves the value of a key from the highest priority layer that has a value
72 73 74 75 76 77 |
# File 'lib/layered_hash.rb', line 72 def get(key) @layers.reverse_each do |_, hash| return hash[key] if hash.key?(key) end nil end |
#get_from_layer(layer, key) ⇒ Object
Retrieves the value of a key from the specified layer
80 81 82 83 84 85 86 |
# File 'lib/layered_hash.rb', line 80 def get_from_layer(layer, key) if @layers.key?(layer) @layers[layer][key] else raise ArgumentError, "Layer #{layer} does not exist" end end |
#merge(*args) ⇒ Object
88 89 90 91 92 |
# File 'lib/layered_hash.rb', line 88 def merge(*args) @layers.merge(*args).tap { |ret| pp([__LINE__, "LayeredHash.merge", '->', ret]) if $pd } end |
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
94 95 96 |
# File 'lib/layered_hash.rb', line 94 def respond_to_missing?(method_name, include_private = false) @layers.key?(method_name.to_sym) || super end |
#set(layer, key, value) ⇒ Object
Sets a key-value pair in the specified layer
99 100 101 102 103 104 105 |
# File 'lib/layered_hash.rb', line 99 def set(layer, key, value) if @layers.key?(layer) @layers[layer][key] = value else raise ArgumentError, "Layer #{layer} does not exist" end end |
#set_current_layer(layer) ⇒ Object
Sets the current layer for use with hash notation ([])
108 109 110 111 112 113 114 |
# File 'lib/layered_hash.rb', line 108 def set_current_layer(layer) if @layers.key?(layer) @current_layer = layer else raise ArgumentError, "Layer #{layer} does not exist" end end |
#to_h ⇒ Object
116 117 118 |
# File 'lib/layered_hash.rb', line 116 def to_h @layers.to_h end |