16

Consider the following simple code which dumps the global context:

var = 5;
DumpSave["test.mx", "Global`"];

Now, in a new notebook, I would like to import var in another context. Trying

Begin["myContext`"]
<< "test.mx"
End[]

does not work because var remains in the global context. Is there a solution?

Thank you.

Massimo Ortolano
  • 727
  • 6
  • 14

1 Answers1

24

Using Begin and End won't help, because .mx files are lower-level and the way they are loaded is different from normal packages.

I was about to say that this isn't possible, but here is a hack which seems to work:

ClearAll[loadInContext];
loadInContext[context_String,file_String/;FileExtension[file]==="mx"]:=
    Module[{tag},
        Block[{$NewSymbol=Sow[#1,tag]&},
            With[{created=(If[#1==={},{},First[#1]]&)[Reap[Import[file],tag][[2]]]},
                Scan[(Context[#1]=context)&,created]
            ]
        ]
    ]

You can use this as, for example:

loadInContext["MyContext`", "test.mx"}]

It is based on a rather interesting and little-known feature, that the assignment like

Context[sym] = newContext

will move the symbol (together with the global rules possibly attached to it) to a new context.

Leonid Shifrin
  • 114,335
  • 15
  • 329
  • 420
  • Does this prevent a name collision for Symbols already defined in Global? – Mr.Wizard May 01 '14 at 11:39
  • @Mr.Wizard No, it doesn't. If the symbol has been already defined in Global`, this method won't work for it, because then $NewSymbol won't fire. – Leonid Shifrin May 01 '14 at 11:41
  • I was afraid of that. +1 for Context[sym] = newContext alone however, which I either wasn't aware of or forgot. – Mr.Wizard May 01 '14 at 11:41
  • 1
    @Mr.Wizard Thanks for the upvote. Very few people know about this Conext[sym]= thing, I think (I mean, outside of WRI). I discovered it myself some time ago, but I am sure I haven't seen any single mention of this thing anywhere on SO, SE of MathGroup. This was a good opportunity to mention it. – Leonid Shifrin May 01 '14 at 11:43
  • Sadly it is an "I forgot" as is all too common for me these days. I mentioned it here: (7912984) – Mr.Wizard May 01 '14 at 11:44
  • @Mr.Wizard But you can get around this problem with name collisions by first moving entire Global context to a temporary one, then loading, then moving it back. – Leonid Shifrin May 01 '14 at 11:45
  • 1
    @Mr.Wizard Why sadly? Turns out you knew it too. Apparently I was also in that comment discussion, but my lack of response to your comment shows that I knew this by then. This doesn't change the fact that there aren't many people who know about it. It just shows that my memory isn't perfect and I forgot about that comment of yours. – Leonid Shifrin May 01 '14 at 11:47
  • Sadly for me I mean: I spend far too much time relearning things I once knew. – Mr.Wizard May 01 '14 at 11:48
  • @Mr.Wizard I actually thing that this is a good thing. We can't remember all the garbage we see, and something has to be used a few times to not fall under the "garbage" category. This leaves us some free space to remember things useful for us at the moment :) – Leonid Shifrin May 01 '14 at 11:50
  • I'd like to think so but commonly having to ask someone his name three times in the space of an hour when I first meet someone indicates otherwise in my case. – Mr.Wizard May 01 '14 at 11:53
  • @Mr.Wizard Don't worry, happens to me too :) – Leonid Shifrin May 01 '14 at 11:56
  • Thank you, this works perfectly. I had saved the results of several lengthy computations to different files, but each file contained the same variable names and at the beginning I didn't think of assigning different contexts. In this way I can load all the results into a new notebook, without any problem. – Massimo Ortolano May 01 '14 at 12:11
  • @MassimoOrtolano Ok, sounds great! Just keep in mind that this is a very simplistic solution, it will convert all symbols created during the file loading, into the context you specify. For more complex cases, one might need a more elaborate scheme. – Leonid Shifrin May 01 '14 at 12:19
  • 4
    @Mr.Wizard as to failing to remember names, when I first met my wife, I could not remember her name to save my life, and she the same. This was despite the fact we were both interested in each other. For some reason, each others' names took a long time to stick. – rcollyer May 01 '14 at 13:01
  • @rcollyer That makes me feel better. :-) – Mr.Wizard May 01 '14 at 19:49
  • +1 because I think I really didn't know this. However it seems the parser can find the new symbol even when the new context isn't on the path. Is it expected? If so, this is peculiar too – Rojo May 03 '14 at 01:29
  • 2
    @Rojo I also noticed that. Don't know whether or not this is expected, may be not. But apparently, this opens a possibility to import separate symbols into other contexts, rather than entire contexts - which is quite nice. Not sure though that one can rely on this feature. I will ask around, when I get some time. – Leonid Shifrin May 03 '14 at 13:10