EasyConfig
- EasyConfig provides an easy-to-use nested
AbstractDict{Symbol, Any}
data structure. - The advantages over other
AbstractDict/NamedTuple
s are:
1) Intermediate levels are created on the fly:
c = Config()
c.one.two.three = 1
- This is super convenient for working with JSON specs (e.g. PlotlyLight.jl).
- As you'd expect, you can
JSON3.write(c)
into a JSON string.
Compare this to OrderedDict
and NamedTuple
:
c = OrderedDict(:one => OrderedDict(:two => OrderedDict(:three => 1)))
c = (one = (two = (three = 1,),),)
c = (; one = (;two = (;three = 1)))
Symbol
/AbstractString
with (getproperty
/getindex
) works.
2) Any combination of - For working with
Config
s interactively,getproperty
is the most convenient to work with. - For working with
Config
s programmatically,getindex
is the most convenient to work with. - This gives you the best of both worlds.
# getproperty
c.one.two.three
c."one"."two"."three"
# getindex
c[:one][:two][:three]
c["one"]["two"]["three"]
# mix and match
c["one"].two."three"
- You can similarly use
setproperty!
/setindex!
in the same way:
c["one"].two."three" = 5
c.one.two.three == 5 # true
Note
- If you try to access something that doesn't exist, an empty
Config()
will sit there. - This is a consequence of creating intermediate levels on the fly.
- Clean up stranded empty
Config
s withdelete_empty!(::Config)
.
c = Config()
c.one.two.three.four.five.six == Config()
# Internally we make the assumption that empty Config's shouldn't be there.
# Some functions will therefore call `delete_empty!` under the hood:
isempty(c) == true