Class: NavigableHash

Inherits:
Hash show all
Defined in:
lib/roda/component/navigable_hash.rb

Instance Method Summary collapse

Methods inherited from Hash

#deep_merge, #extract!, #indifferent, #slice, #slice!, #to_obj

Constructor Details

#initialize(constructor = {}, &block) ⇒ NavigableHash

Returns a new instance of NavigableHash.



3
4
5
6
7
8
9
10
11
12
# File 'lib/roda/component/navigable_hash.rb', line 3

def initialize(constructor = {}, &block)
  if block_given?
    yield self
  elsif constructor.is_a?(Hash)
    super()
    update(constructor)
  else
    super(constructor)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object (private)



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/roda/component/navigable_hash.rb', line 193

def method_missing(m, *args, &block)
  m = m.to_s
  if m.chomp!('=') && args.count == 1
    set_and_cache_value(m, *args)
  elsif args.empty? && block_given?
    self.navigate_hash_from_block m, &block
  elsif args.empty?
    get_and_cache_value(m)
  else
    fail ArgumentError, "wrong number of arguments (#{args.count} for 0)"
  end
end

Instance Method Details

#==(other_hash) ⇒ Object



17
18
19
# File 'lib/roda/component/navigable_hash.rb', line 17

def ==(other_hash)
  to_hash == self.class.new(other_hash).to_hash
end

#[](key) ⇒ Object



32
33
34
# File 'lib/roda/component/navigable_hash.rb', line 32

def [](key)
  get_value convert_key(key)
end

#[]=(key, value) ⇒ Object Also known as: store

Assigns a new value to the hash:

hash = NavigableHash.new
hash[:key] = "value"


26
27
28
# File 'lib/roda/component/navigable_hash.rb', line 26

def []=(key, value)
  set_value convert_key(key), navigate(value)
end

#convert_array_for_to_hash(value) ⇒ Object



140
141
142
# File 'lib/roda/component/navigable_hash.rb', line 140

def convert_array_for_to_hash(value)
  value.map { |item| convert_for_to_hash item }
end

#convert_for_to_hash(value) ⇒ Object



121
122
123
124
125
126
127
128
129
130
# File 'lib/roda/component/navigable_hash.rb', line 121

def convert_for_to_hash(value)
  case value
  when NavigableHash
    convert_navigable_hash_for_to_hash value
  when Array
    convert_array_for_to_hash value
  else
    convert_value_for_to_hash value
  end
end

#convert_key(key) ⇒ Object



132
133
134
# File 'lib/roda/component/navigable_hash.rb', line 132

def convert_key(key)
  key.kind_of?(Symbol) ? key.to_s : key
end

#convert_navigable_hash_for_to_hash(value) ⇒ Object



136
137
138
# File 'lib/roda/component/navigable_hash.rb', line 136

def convert_navigable_hash_for_to_hash(value)
  value.to_hash
end

#convert_value_for_to_hash(value) ⇒ Object



144
145
146
# File 'lib/roda/component/navigable_hash.rb', line 144

def convert_value_for_to_hash(value)
  value
end

#delete(key) ⇒ Object

Removes a specified key from the hash.



37
38
39
# File 'lib/roda/component/navigable_hash.rb', line 37

def delete(key)
  super(convert_key(key))
end

#dupObject

Returns an exact copy of the hash.



42
43
44
# File 'lib/roda/component/navigable_hash.rb', line 42

def dup
  self.class.new to_hash
end

#fetch(key, *extras) ⇒ Object

Same as Hash#fetch where the key passed as argument can be either a string or a symbol:

counters = NavigableHash.new
counters[:foo] = 1

counters.fetch("foo")          # => 1
counters.fetch(:bar, 0)        # => 0
counters.fetch(:bar) {|key| 0} # => 0
counters.fetch(:zoo)           # => KeyError: key not found: "zoo"


57
58
59
# File 'lib/roda/component/navigable_hash.rb', line 57

def fetch(key, *extras)
  super(convert_key(key), *extras)
end

#key?(key) ⇒ Boolean Also known as: include?, has_key?, member?

Checks the hash for a key matching the argument passed in:

hash = NavigableHash.new
hash["key"] = "value"
hash.key? :key  # => true
hash.key? "key" # => true

Returns:

  • (Boolean)


68
69
70
# File 'lib/roda/component/navigable_hash.rb', line 68

def key?(key)
  super(convert_key(key))
end

#merge(hash) ⇒ Object

Merges the instantiated and the specified hashes together, giving precedence to the values from the second hash. Does not overwrite the existing hash.



78
79
80
# File 'lib/roda/component/navigable_hash.rb', line 78

def merge(hash)
  self.dup.update(hash)
end


148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/roda/component/navigable_hash.rb', line 148

def navigate value
  case value
  when self.class
    value
  when Hash
    navigate_hash value
  when Array
    navigate_array value
  else
    navigate_value value
  end
end


165
166
167
# File 'lib/roda/component/navigable_hash.rb', line 165

def navigate_array(value)
  value.map { |item| navigate item }
end


161
162
163
# File 'lib/roda/component/navigable_hash.rb', line 161

def navigate_hash(value)
  self.class.new value
end


173
174
175
# File 'lib/roda/component/navigable_hash.rb', line 173

def navigate_hash_from_block(key, &block)
  self[key] = self.class.new &block
end


169
170
171
# File 'lib/roda/component/navigable_hash.rb', line 169

def navigate_value(value)
  value
end

#respond_to?(m, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/roda/component/navigable_hash.rb', line 82

def respond_to?(m, include_private = false)
  has_key?(m) || super
end

#to_hashObject



86
87
88
89
90
# File 'lib/roda/component/navigable_hash.rb', line 86

def to_hash
  reduce({}) do |hash, (key, value)|
    hash.merge key.to_sym => convert_for_to_hash(value)
  end
end

#update(other_hash) ⇒ Object Also known as: merge!

Updates the instantized hash with values from the second:

hash_1 = NavigableHash.new
hash_1[:key] = "value"

hash_2 = NavigableHash.new
hash_2[:key] = "New Value!"

hash_1.update(hash_2) # => {"key"=>"New Value!"}


102
103
104
# File 'lib/roda/component/navigable_hash.rb', line 102

def update(other_hash)
  other_hash.reduce(self) { |hash, (k, v)| hash[k] = navigate(v) ; hash }
end

#values_at(*indices) ⇒ Object

Returns an array of the values at the specified indices:

hash = NavigableHash.new
hash[:a] = "x"
hash[:b] = "y"
hash.values_at("a", "b") # => ["x", "y"]


115
116
117
# File 'lib/roda/component/navigable_hash.rb', line 115

def values_at(*indices)
  indices.collect {|key| self[convert_key(key)]}
end