JuliaIO / JLD2.jl

HDF5-compatible file format in pure Julia
Other
553 stars 88 forks source link

Option to load all variables from JLD2 file into global scope #564

Closed nathanrboyer closed 3 months ago

nathanrboyer commented 3 months ago

I do not see a way to load variables without specifying new variables names. The variable names are already in the file!

I am currently using this workaround, and think something like this should have a convenient function in the package.

julia> data = load(file)
Dict{String, Any} with 9 entries:
  "user_input"         => (spec_no = "SA-723", type_grade = "3", class_condition_temper = "2", KM620_coefficients_table_material_category = "Ferritic steel", num_plastic_points = 2…
  "interpolants"       => (yield_interp = 15-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Float64}, Gridded(Linear())), Line()) with element type Float64:…
  "num_plastic_points" => 20
  "material_category"  => "Ferritic steel"
  "df"                 => 15×14 DataFrame…
  "searchrange"        => (10.0, 1.0e6)
  "eq"                 => plasticity
  "temperatures"       => [100, 150, 200, 250, 300, 400, 500, 600, 650, 700, 750, 800, 850, 900, 950]

julia> for (key, value) in data
           Core.eval(Main, :($(Symbol(key)) = $value))
       end

I mostly use this package when I need to restart my REPL but don't want to lose progress on the variables I've generated so far.

13299118606 commented 3 months ago

You can simply load it by changing the variable to the appropriate format, such as my function to save the workspace, similar to jldsave("example.jld2"; z=x, x=y, y=3)

function save_workspace(outname="workspace.jld2")
    variable_names = Base.names(Main)
    workspace = Dict{Symbol, Any}()

    for var_name in variable_names
         if (~isa((@eval Main.$(Symbol(var_name))),Function) && (~(@eval Main.$(Symbol(var_name)) in  [nothing,Main,Base,Core])) 
            && !isa((@eval Main.$(Symbol(var_name))), Module) && !isstructtype(@eval Main.$(Symbol(var_name))))
            try
                workspace[Symbol(var_name)] = eval(Meta.parse(string(var_name)))
            catch e
                println("Cannot save variable $var_name: $e")
            end
        end

    end

    varstring = join(
    ["$k=$(typeof(workspace[k]) == String ? "\"$(workspace[k])\"" : workspace[k])" for k in keys(workspace)],
    ","
    )

    savestring="JLD2.jldsave(\"$outname\","*varstring*")"
    @eval Main Meta.parse(savestring)
end

Use Save workspace and load workspace

save_workspace()

@load "workspace.jld2"

I hope the developer will improve this workspace saving function into the project, many people have this demand

JonasIsensee commented 3 months ago

This functionality has existed for many years in @save filename (without further args) and @load "path/to/file".

However, not every object can be stored with JLD2 and there are conceptual problems. (only works interactively and not in module / no functions / no modules / no struct defs) Due to this, there was a constant stream of complaints for years before this functionality was eventually removed from documentation.