Save variables to .mat file or .jld2 file by metaprogramming

Here is a normal code to save variables to mat file (no variable name modification)

using FileIO, MAT
a = 1
b = 2
c = 3
matwrite("savemat.mat", Dict("a" => a,"b" => b, "c" => c))

The question is: How can I write a function or a macro to like this.

savetomatfile("savemat.mat",a,b,c)

I know only basics of metaprogramming.

This is a really good use-case for a macro. In fact, JLD2 already has @save which does basically what you are looking for.

If you want to learn how to implement this yourself, I would suggest starting with a simpler macro that takes a set of variable names and produces the dictionary mapping those names as strings to their current values.

This might help you start off:

julia> macro map_name_to_value(variable::Symbol)
         quote
           $(string(variable)) => $(esc(variable))
         end
       end
@map_name_to_value (macro with 1 method)

julia> a = 1
1

julia> @map_name_to_value a
"a" => 1

That macro just takes a single variable and produces "variable name" => value. You could extend that to take multiple variables in and then construct a dict out of those name => value pairs.

Finally, you could change your macro to call “matwrite” with that dict.

3 Likes

Thanks,
I’m stuck with how to get the value inside loop in the macro

a = 1
b = 2
c = 3
macro map_name_to_value2(vars::Symbol...)
   quote
       for var in $(esc(vars))
           println(var)
       end
   end
end
julia> @map_name_to_value2(a,b,c)
a
b
c

Can you tell me how to get the values (i.e, 1,2,3)?

Hi,
the trick is to interpolate with $.

If you want to have a look at something more advanced that does something similar to what you want, have a look at the @save macro of JLD2 defined in src/loadsave.jl

1 Like

I changed from

println(var)

to

println(eval(var))

Then I get the values 1,2,3