15
$\begingroup$

I have a notebook I wish to set up where the sections are conceptually related to each other. But, I wish to isolate them from each other programmatically, so that they do not interfere with one another. A built-in method of doing this is to set the default context to CellGroup so that each group of cells has its own context. However, each section relies on the same set packages, and because one of them is quite large, I do not wish to reload the packages for each section. An option is to put each section in its own context manually using Begin and End, but I would rather avoid that if possible. Ideally, though, I would like to be able to load the packages in their own separate section and elevate them to the Global` (or equivalent) context. Any thoughts on how this can be accomplished?

$\endgroup$

2 Answers 2

14
$\begingroup$

One possibility would be to modify the notebook's stylesheet so that Input cells (or a clone) have something like:

CellProlog -> ($ContextPath = DeleteDuplicates[Prepend[$ContextPath,"abc`"]])

Then your package's context should be available to all the code:

enter image description here

$\endgroup$
2
  • $\begingroup$ Ah, brilliant. That should have occurred to me, +1. What about loading in packages though? ;) $\endgroup$
    – rcollyer
    Aug 18, 2012 at 3:16
  • $\begingroup$ Possibly the Prolog could be a Needs statement, though I haven't checked to see if it would actually create symbols in the package context correctly. $\endgroup$ Aug 18, 2012 at 3:47
2
$\begingroup$

Below Brett's answer:

Ah, brilliant. That should have occurred to me, +1. What about loading in packages though? ;) – rcollyer

Perhaps you know this but Packages are already loaded to a shared context in the sense that doing Get["package`"] loads the definitions into (typically) the context package`, and the definitions are available from any other Cell Group by using the fully qualified name.

What remains is getting e.g. package` into the $ContextPath. Brett's method works if you know the package contexts ahead of time, but we may want to adapt it to use a (true) global list of shared contexts. For example we could use Global`$sharedContexts to store any contexts to be shared across Cell Groups and then set CellProlog to:

($ContextPath = DeleteDuplicates @ Join[Global`$sharedContexts, $ContextPath])

Starting with Global`$sharedContexts = {}; we could then load a package with:

<< "Combinatorica`"
AppendTo[Global`$sharedContexts, "Combinatorica`"];

Or we could use a custom Needs-type function stored in the System` context (to make it easily accessible), or we could perhaps modify BeginPackage like this:

Unprotect[BeginPackage]

BeginPackage[con_, x___] /; ! TrueQ[$shrCntxtMod] :=
     Block[{$shrCntxtMod = True},
       BeginPackage[con, x];
       If[
         ValueQ @ $sharedContexts,
     AppendTo[$sharedContexts, con],
         $sharedContexts = {con}
   ]
 ]

Which will add any context created with BeginPackage to Global`$sharedContexts.

$\endgroup$
3
  • $\begingroup$ Hmm, two years and I haven't upvoted this? Bad user. +1 $\endgroup$
    – rcollyer
    Nov 7, 2014 at 2:42
  • $\begingroup$ @rcollyer Thanks for acknowledging. :-) Sometimes I wonder if anybody read an answer like this with few or no votes. $\endgroup$
    – Mr.Wizard
    Nov 8, 2014 at 15:16
  • $\begingroup$ I had read it, but I wanted to go through it before I voted on it, and then I forgot about it. :) $\endgroup$
    – rcollyer
    Nov 8, 2014 at 18:25

Your Answer

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

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