Design¶
MergedOptions is designed like a cursor
looking at some storage
where
each MergedOptions instance is just a different position in the same storage
.
Storage¶
When you add data to a MergedOptions instance the code will store a tuple of
the prefix
(path from the root of the options to this data), the data
itself as a option_merge.versioning.VersionedDict
; and the source
of the data, which is specified when you add data to the MergedOptions.
We are able to use this information to convert the storage into a dictionary; to find nested values; and importantly, to memoize access to keys.
Everytime you access a dictionary in the MergedOptions
you get back a new
instances of MergedOptions
that has a different prefix into the same storage.
VersionedDict¶
To support memoizing values, all dictionaries are converted into a versioned dict.
This is just a normal dictionary but it supports a version
that is incremented
each time the dictionary is modified in some way.
This way we can invalidate a cache of accessed values when the version of the underlying data changes.
See option_merge.versioning.VersionedDict
for more information on this
data structure.
Data access¶
There are two ways to access data via a MergedOptions
instance. The first is
via string access:
m = MergedOptions.using({"a": {"b": 3}})
assert m["a.b"] == 3
And the second is via array access:
m = MergedOptions.using({"a": {"b": 3}})
assert m[["a", "b"]] == 3
The string access will match on the longest match. This is a deliberate decision so that keys are not split by dots:
m = MergedOptions.using({"a.b": 2, "a": {"b": 3}})
assert m["a.b"] == 2
assert m[["a", "b"]] == 3
In that example, a.b
will match the “a.b” key rather than going into the
“a” key and accessing it’s “b” member.
The array access, however, will not do such matching and treats each item in the array as a full key.
Setting data¶
Just like accessing data, there are two ways of setting data in a MergedOptions
:
with strings and with arrays.
In both cases, data is added to the storage, rather than trying to modify any existing data.