1
$\begingroup$

This is question is also posted at the Wolfram site here. The files are available there as well.

I have a need to make use of a list of associations for fast lookup inside a Package implementation. To do this, I have produced the list in a notebook, saved it to the variable assoc1, and then DumpSaved that to file assoc1.mx. I have written a package assoc1Package.m saved from assoc1Package.nb. The package does two things: 1) It Gets assoc1.mx into the global context; and 2) it defines a function f[x_] as assoc1[x] and makes it available with a usage. It expects that a notebook which loads the package will be able to use f[x] to look up the value in assoc1 corresponding to the key x. This is tried in testAssoc1.nb.

What I find is that the function returns the assoc1[key] unevaluated. However, if the association list is generated within the package, rather than imported by get, it works. The fact that assoc1 is itself defined indicates the Get did work.

I realize I could just load the mx file in my notebook and use assoc1 directly. But this is a simplified example. In reality I want a lot of this inside the package available to functions defined in the package.

I have tried loading the mx file in the package both before and after Private, with the same result. When it is loaded before Private, assoc1 does appear in the global context.

Here is the code for the package and test notebook. The mx file is available at the Wolfram site.

Package:

BeginPackage["assoc1Package`"];
Get["C:\\Users\\David\\Documents\\Mathematica files\\A in P\\assoc1.mx"];
f::usage="return assoc1[x]"
Begin["`Private`"];
f[x_]:=assoc1[x]
End[];
EndPackage[]

Test notebook: (posted as image because of copy issues ) enter image description here

$\endgroup$
3
  • $\begingroup$ To add to Shadowray's comment: this is specific to MX. Other formats (including a plain .m file produced by Save) will not usually behave this way. $\endgroup$
    – Szabolcs
    May 21, 2017 at 16:30
  • $\begingroup$ The problem is that Get loads variables exactly to the same context they were DumpSaved. Thus it doesn't matter if you place Get before or after Begin["`Private`"]. $\endgroup$
    – Ray Shadow
    May 21, 2017 at 16:35
  • $\begingroup$ A possible workaround is described here: Importing an mx file into a context. See also limitations (related to name collisions) mentioned there in comments. $\endgroup$
    – Ray Shadow
    May 21, 2017 at 16:38

1 Answer 1

4
$\begingroup$

the easiest while not really nice way to solve this is to explicitly add the global context into your code:

BeginPackage["assoc1Package`"];
Get["C:\\Users\\David\\Documents\\Mathematica files\\A in P\\assoc1.mx"];
f::usage="return assoc1[x]"
Begin["`Private`"];
f[x_]:=Global`assoc1[x]
End[];
EndPackage[]

if you really did save Global`assoc1 then that should work.

That said, for your usecase I would strongly suggest to not save the variable name to the mx file, but only the association. That can be done with

Export[filename,Global`assoc1]

once. You could then in your package load the association to a package-private variable:

BeginPackage["assoc1Package`"];
f::usage="return assoc1[x]"
Begin["`Private`"];
assoc1 = Import[filename];
f[x_]:=assoc1[x];
End[];
EndPackage[]

... which would nicely encapsulate the internals of how you store that data.

Finally you should keep in mind that the mx format is not entirely platform independent, there are differences between 32bit and 64bit versions and older versions are not guaranteed to be able to load mx-files from newer versions.

EDIT as Shadowray has mentioned in a comment loading the file generated with Export will need Import not Get to reload. I have corrected the code accordingly

$\endgroup$
1
  • $\begingroup$ @David Keith, If you use Export["exported.mx", Global`assoc1] to save a variable in MX file, then you should use assoc1 = Import["exported.mx"] instead of Get, because assoc1 = Get["exported.mx"] will set assoc1 to Null. $\endgroup$
    – Ray Shadow
    May 25, 2017 at 21:12

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.