Define a set of configurations as a single, more abstract and comprehensive meta-configuration.
] add MetaConfigurations
Besides providing functions for manipulating configurations, MetaConfigurations.jl is also a meta package for a common API through which configuration file handlers like JSON.jl and YAML.jl are unified.
Assume you want to describe four experiments, each of which consists of a combination of two parameters.
# experiment 1
description: "Experiment with α=0.1 and β=95%"
alpha: 0.1
beta: 95%
# experiment 2
description: "Experiment with α=0.01 and β=95%"
alpha: 0.01
beta: 95%
# experiment 3
description: "Experiment with α=0.1 and β=97.5%"
alpha: 0.1
beta: 97.5%
# experiment 4
description: "Experiment with α=0.01 and β=97.5%"
alpha: 0.01
beta: 97.5%
MetaConfigurations.jl can derive these combinations from a single, more abstract and comprehensive representation, which we call a meta-configuration:
description: "Experiment with α=$(alpha) and β=$(beta)"
alpha:
- 0.1
- 0.01
beta:
- 95%
- 97.5%
The desired list of experiments is obtained from this meta-configuration by expansions and String interpolations:
using MetaConfigurations
configurations = expand(
parsefile("example.yml"), # read the above meta-configuration
"alpha",
"beta"
) # create a list of cells from the matrix spanned by alpha and beta
interpolate!.(configurations, "description") # fill in the placeholders in each description
Let's take a closer look on the operations provided by this package. We have already seen the first two of them.
MetaConfigurations.expand:
We can expand any property that has a vector of values, like the properties alpha
and beta
in the example above.
Consider at first the expansion of a single vector-valued property p
with length n
.
This expansion will result in a vector of n
configurations, in each of which p
has only one of its initial values.
The expansion of multiple properties, like above, is taken out sequentially.
By expanding properties, we transform a single, comprehensive meta-configuration into a set of configurations.
MetaConfigurations.interpolate:
Interpolation substitutes all placeholders in a String
property with the corresponding values of other properties in the same configuration.
In the above example, we have seen how the placeholders $(alpha)
and $(beta)
have been replaced with the actual values of alpha
and beta
.
MetaConfigurations.patch:
A patch defines an additional key-value pair in a copy of a configuration.
For example, we might want wo create a copy of the above configurations
vector in which each configuration has a fixed value for an additional property gamma
:
patch.(configurations; gamma=1000)
MetaConfigurations.jl is also a meta-package that unifies the APIs of JSON.jl and YAML.jl. To which backend an operation is delegated is automatically determined from the file name extension.
using MetaConfigurations
cfg = parsefile("example.yml") # read from a YAML file
save("example.json", cfg) # store it as a JSON file
By default, MetaConfigurations.jl parses files into objects of the type Dict{String,Any}
. You can change this behaviour through the dicttype
argument, e.g. to preserve the order of the configuration file or to use Symbol
instances as keys.
using MetaConfigurations, OrderedCollections
cfg = parsefile("example.yml", dicttype=OrderedDict{Symbol, Any})
You can recursively find properties by their key:
# continuing the introductory example, ..
find(configurations, "description")
4-element Array{String,1}:
"Experiment with α=0.1 and β=95%"
"Experiment with α=0.1 and β=97.5%"
"Experiment with α=0.01 and β=95%"
"Experiment with α=0.01 and β=97.5%"