Skip to main content

evaluation - How to properly DumpSave & Get Global`s symbols inside packages while not touching Global context?


For efficiency reasons I prefer to use DumpSave instead of Save.


For ease of access I prefer to save symbols in DumpSaved files inside Global` context.


But when my code evolved and I moved it inside packages I found a lot of problems to read symbols from those DumpSaved files so that read & write process




  • allows for use saved variables inside my package (and its context)

  • does not affect variables in Global`

  • When user loads the file directly with Get, bypassing my package (and perhaps not even loading it), the symbol is available in Global` context for him or her

  • symbol name is not hard-coded into function (but of course it must hard-coded into the file itself :-( )


Simply put: I want to use DumpSave & Get the way I use Export & Import, but with efficiency and flexibility benefits.


I come up with the following code, but it still messes the Global context and has the symbol name hardcoded (Global`myglobalname):


SaveMySymbol[object_,path_String]:= Block[{},
OwnValues[Global`myglobalname] = HoldPattern[Global`myglobalname] :> object;

DumpSave[
path<>".mx", Global`myglobalname]];

LoadMySymbol[path_String]:= Block[{strfullpath},
strfullpath = path<>".mx";
If[FileExistsQ[strfullpath], Get[strfullpath]; Global`myglobalname,
Null]]

I guess the problem with messing the Global` context can be avoided by caching the maybe existing definition of Global`myglobalname symbol and returning it back after Get. But the code look already awfully complex (it took me a full day to figure out the trick with OwnValues) and I suspect that there must be an easy way... Well, so far there always was one with Mathematica...



Answer




To show how this is possible:



Simply put: I want to use DumpSave & Get the way I use Export & Import, but with efficiency and flexibility benefits.



You can simply use Import and Export. They do support the same format that DumpSave uses, and they give you the same performance. But they don't save symbol names.


Export["data.mx", data, "MX"]

data = Import["data.mx"]

MX files are not portable between architectures though, so you may consider using Compressed strings, as described here. This is several times slower, but it's still quite fast compared to any other alternative and it's portable.



If you ever need to save InterpolatingFunctions, please be aware of this problem.


Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...