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?
2 Answers
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:
-
$\begingroup$ Ah, brilliant. That should have occurred to me, +1. What about loading in packages though? ;) $\endgroup$– rcollyerAug 18, 2012 at 3:16
-
$\begingroup$ Possibly the
Prolog
could be aNeeds
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
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
.
-
$\begingroup$ Hmm, two years and I haven't upvoted this? Bad user. +1 $\endgroup$– rcollyerNov 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$ 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$– rcollyerNov 8, 2014 at 18:25