4
$\begingroup$

Notebook A wants to open, display, and possibly run Notebook B without corrupting its operating environment, and then resume, possibly repeating the exercise with Notebook C.

A lttile more detail: Notebook A offers the user a menu of notebook B's to examine and, at the user's discretion, execute. However, executing notebook B risks changing the values of variables with names common to both notebooks. An obvious problem.

I have experimented with launching a separate kernel, but I am informed that examining notebook B requires a front end. And I don't know how to provide it.

I manually loaded Mathematica twice and ran notebooks A and B independently. That led me to experiment with StartProcess to see if I could accomplish the same thing programmatically, but I have not been successful.

$\endgroup$
3
  • $\begingroup$ One notebook running another is described in answers to 67050 and, I believe, elsewhere on this site. $\endgroup$
    – bbgodfrey
    Jan 20, 2017 at 0:20
  • $\begingroup$ I doubt there's a foolproof way to prevent things like Unprotect[Times]; Times = Plus; Protect[Times] and Global`foo = 0 that will change the calling notebook's state. If you can assume notebooks B, C, etc. are "well-behaved", then there might be a way with the option CellContext. $\endgroup$
    – Michael E2
    Jan 20, 2017 at 0:44
  • $\begingroup$ Related: (29779). Possible duplicate: (92347) $\endgroup$
    – Mr.Wizard
    Jan 20, 2017 at 8:26

1 Answer 1

4
$\begingroup$

If you use a different Mathematica kernel to run "Notebook B", then the state of the current kernel will not be affected.

First, consider these questions:

  • Do you really need a notebook? Can't you just put the code in a plain text file (an .m script)?

  • If you do need a notebook, do you really need to display it? Or is it sufficient to just run it?

The simplest way to run a script (plain text file with code) is to invoke the second kernel as you would invoke any other process: Run["math -script myscript.m"]. You will need to use the full path to and correct name of the kernel executable. There will be no interaction between your current kernel and the subsidiary kernel.

If you really need to run a notebook, evaluate NotebookEvaluate in the subsidiary kernel. It can take a file name. A command line like the following should work, but I haven't tested it:

math -run 'NotebookEvaluate["book.nb"]; Quit[]'

Do check the InsertResults option of NotebookEvaluate.

If you also want to display that notebook, then things get much more messy. I don't want to go into this unless you make your question more specific, because there are many things which may or may not go wrong, depending on what specific things you are doing and what is contained in your notebook. In principle you could NotebookOpen the notebook, set up a new evaluator in the kernel configuration option, set the evaluator of the notebook to that new kernel, then evaluate the notebook. But it's not robust. What if your notebook has dynamic elements? They may auto-evaluate upon opening.

It is also possible, in principle, to control the subsidiary kernel through MathLink. I have done this, precisely with the goal to evaluate notebooks in a separate environment (although I did not need to display them). While I now have a setup that works for my specific use case, I hit some problems and some version-dependent bugs on the way, so I don't recommend this approach unless you know that you need it and you are prepared to spend a lot of time.

$\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.