Module: Hamster::Associable
Overview
Including Associable
in your container class gives it an update_in
method.
To mix in Associable
, your class must implement two methods:
fetch(index, default = (missing_default = true))
put(index, item = yield(get(index)))
get(key)
See Vector#fetch, Vector#put, Hash#fetch, and Hash#put for examples.
Instance Method Summary collapse
-
#dig(key, *rest) ⇒ Object
Return the value of successively indexing into a collection.
-
#update_in(*key_path) {|value| ... } ⇒ Associable
Return a new container with a deeply nested value modified to the result of the given code block.
Instance Method Details
#dig(key, *rest) ⇒ Object
Return the value of successively indexing into a collection.
If any of the keys is not present in the collection, return nil
.
keys that the Hamster type doesn't understand, raises an argument error
62 63 64 65 66 67 68 69 |
# File 'lib/hamster/associable.rb', line 62 def dig(key, *rest) value = get(key) if rest.empty? || value.nil? value elsif value.respond_to?(:dig) value.dig(*rest) end end |
#update_in(*key_path) {|value| ... } ⇒ Associable
Return a new container with a deeply nested value modified to the result
of the given code block. When traversing the nested containers
non-existing keys are created with empty Hash
values.
The code block receives the existing value of the deeply nested key/index
(or nil
if it doesn't exist). This is useful for "transforming" the
value associated with a certain key/index.
Naturally, the original container and sub-containers are left unmodified; new data structure copies are created along the path as needed.
36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/hamster/associable.rb', line 36 def update_in(*key_path, &block) if key_path.empty? raise ArgumentError, "must have at least one key in path" end key = key_path[0] if key_path.size == 1 new_value = block.call(fetch(key, nil)) else value = fetch(key, EmptyHash) new_value = value.update_in(*key_path[1..-1], &block) end put(key, new_value) end |