# Globally loading packages while using a CellGroup as the default context

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?

-

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:

-
Ah, brilliant. That should have occurred to me, +1. What about loading in packages though? ;) –  rcollyer Aug 18 '12 at 3:16
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. –  Brett Champion Aug 18 '12 at 3:47

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`.

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