2
$\begingroup$

As many others (I guess) I'm struggling with the handling of contexts within Mathematica. I'm working on a new package definition with the usual syntaxt specified by the Mathematica documentation:

BeginPackage["example`"];

<Entry Points>

Begin["`Private`"]

<Definitions>

End[];

EndPackage[];

Now I want to use symbols generated in another Notebook and saved with DumpSave for efficiency. The code in this other Notebook is thus

DumpSave[<some mx file>,{symbol1,symbol2,...,symboln}]

when I import these symbols into my package it looks like this:

BeginPackage["example`"];

<Entry Points>

Begin["`Private`"]

DumpGet[<some mx file>];
<Definitions>

End[];

EndPackage[];

there is already the catch: The Symbols are not automatically loaded into the private context of the package (which is examplePrivate in the above code snippet) but into the original context of the Notebook where the mx file has been generated (which is Global` in my case)! Thus I need to convert the symbols either into the private context in the package definition (which would the following statements

example`Private`symbol1=Global`symbol1;
example`Private`symbol2=Global`symbol2;
.
.
.
example`Private`symboln=Global`symboln;
Remove[Global`symbol1,Global`symbol2,...,Global`symboln])

or save the symbols already into the right context by using

example`Private`symbol1=symbol1;
example`Private`symbol2=symbol2;
.
.
.
example`Private`symboln=symboln;
DumpSave[<some mx file>,{example`Private`symbol1, example`Private`symbol2, 
  ..., example`Private`symboln}]

in the generating Notebook (which would be my preferred solution). I need to do all of this clumsy setup because I do not want to have the symbols in the Global` context because then the symbols are visible outside of the package, which is not necessary and may cause shadowing problems too. Now my question: Is there a quick way to copy symbols over from one context into another? Something like

Set[Evaluate[example`Private`#],Global`#]&/@{symbol1,symbol2,...,symboln}

would be preferrable. However above statement does not work...

Any ideas?

$\endgroup$
8
  • $\begingroup$ Related: stackoverflow.com/q/7912984/618728, (19902), (3378) $\endgroup$
    – Mr.Wizard
    Mar 14, 2013 at 8:14
  • 3
    $\begingroup$ A simple question: why do you need to load definitions from an MX file in your package? Wouldn't it be better to put everything in plain text and then save the complete package as a .MX file if loading speed is important? $\endgroup$
    – Mr.Wizard
    Mar 14, 2013 at 8:17
  • 2
    $\begingroup$ Second question: you show copying definitions e.g. example`Private`symbol1 = Global`symbol1; -- why not simply change the Context to example`Private` before you define those symbols in the first place? $\endgroup$
    – Mr.Wizard
    Mar 14, 2013 at 8:19
  • 1
    $\begingroup$ @Mr.Wizard question 1: I'm using a Notebook with the autogenerated package option to define the package contents. I prefer this method because the package code is much better readable, because of the excellent formatting possibilities for Notebooks compared to .m files. Furthermore what goes into the package can be easily defined through the initialization cell flag. However the parameters I'm talking about are interpolation statements which are generated with a lot of data-crunching from measured data where I simply do not want to burden the package definition with, just for size reasons. $\endgroup$
    – Rainer
    Mar 14, 2013 at 13:25
  • $\begingroup$ @Mr.Wizard question 2: Fair point. I initially used XML files for the transfer of the symbols and there the context is not preserved (Importing symbols from XML files just read in the short form of the symbol name and thus drop the context definition). However with the growing amout of XML files the Import run time increased too. Thus I was forced to switch over to .mx files. Since there are numerous symbols to export/import I would need to correct the context at multiple positions in the Notebook. Change it at one place (at the export) seemed to me the more efficient way. $\endgroup$
    – Rainer
    Mar 14, 2013 at 13:34

1 Answer 1

2
$\begingroup$

I solved my problem now differently. According to my last comment to my question I now just save the interpolation statements within the package into an mx file

DropFileExtension[datafile_] :=StringJoin[Riffle[Most[StringSplit[datafile, "."]], "."]];
DumpMX[datafile_, symbol_: dummy] := Module[{filename},
  filename =DropFileExtension[datafile] <> "_" 
    <>StringReplace[$System, " " -> ""] <> "_" 
    <> ToString[NumberForm[$VersionNumber, {2, 1}]] <> ".mx";
  If[! MatchQ[FindFile[filename], $Failed], 
    DeleteFile[filename]];(*Delete File if it is already existing*)
    symbol = ReadMX[datafile, True];
    DumpSave[filename, symbol];
  ];

ReadMX::MXFileError = "MX file `1` of optical database not found.";
ReadMX[datafile_, symbol_: dummy] := Module[{filename, fields},
 filename = DropFileExtension[datafile] <> "_" 
   <> StringReplace[$System, " " -> ""] <> "_" 
   <> ToString[NumberForm[$VersionNumber, {2, 1}]] <> ".mx";
 If[MatchQ[FindFile[filename], $Failed], 
   Message[ReadMX::MXFileError, filename], Import[filename]];
 Return[symbol];
 ];
]

Any symbol (defined default globally as dummy) is saved into an MX file including the System and Mathematica Version information (since the binary MX file is not transferrable between different systems and versions) in the name.

DumpMX["test.mx",dummy]

and can be read by

ReadMX["test.mx",dummy]

.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.