Dictionary to variables in julia

Hey,
I will keep the question simple, so I have a dictionary like this:

my_dict = Dict(“dataFolder”=> “my_data”, “tile_size” => [100, 200], “dims” => 20)

and I want the keys to be variables as in my workspace with the corresponding dictionary values:

dataFolder = “my_data”
tile_size = [100, 200]
dims = 20

My key values are always a string, but the corresponding value may change.

this is ~bad practice in Julia in general, maybe it’s more common in R or something.

can you describe why you need to do this exactly?

3 Likes

@jling I’m reading a json file that user writes lots of parameters and my Julia program will parse the json and use the parameters as variables.

can’t you just use that json?

2 Likes

yes.

my_dict[“dataFolder”]

would perfectly work but I thought dataFolder as a variable might be more aesthetic? but you are not suggesting, I see. Then I think I will stick with my dictionary.

You could make it look a bit more aesthetic by defining a getproperty method that gives you slightly nicer my_dict.dataFolder syntax instead of my_dict["dataFolder"].

Some limitations of that approach:

  • you need my_dict to be a type that you’ve defined yourself otherwise defining a
    Base.getproperty(d::Dict, s::Symbol) = ...
    
    is definitely type piracy since you own neither Dict, Symbol, nor getproperty. So you’d need to wrap Dict in your own type:
     struct MyDict
        dict::Dict
     end
     Base.getproperty(d::MyDict, s::Symbol) = getfield(d, :dict)[string(s)]
    
  • The keys of the Dict must be valid Julia identifiers, so no dashes, spaces, etc.

You can make values stored in my_dict into variables if you use eval:

mod = Module()
for (k, v) in my_dict
    Core.eval(mod, :($(Symbol(k)) = $v))
end
@assert mod.dataFolder == "my_data"

But as @jling mentioned above, generally this is not what you should be doing, and in this example doesn’t actually provide any benefit over the getproperty approach. It has it’s place at times, but those are pretty limited, and really a last resort.

Another way may be with keyword arguments like:

julia> function use_variables(;
           tile_size = error("tile_size not provided"),
           dataFolder = error("dataFolder not provided"),
           dims = error("dims not provided"),
           kws... # ignore anything else.
       )
           @show tile_size dataFolder dims # use as variables inside function.
           # ...
       end

julia> use_variables(; (Symbol(k)=>v for (k,v) in my_dict)...)
tile_size = [100, 200]
dataFolder = "my_data"
dims = 20
20

Which might work if you only need a predefined set of variables to be handled.

1 Like

Don’t do this. It is bad programming practice in any language.

2 Likes