问题
In mathematica (I am using mma 5.0 ( guess pretty old)), if I type the following as one line:
Needs["Graphics`Master`"]; Animate[Plot[Sin[n x], {x, 0, 2 Pi}, Axes -> False], {n, 1, 6, 1}]
I then got a lot of errors/warnings. But if I type them in separately, it is working fine. How to make it work in one code block?
Thanks!
回答1:
As belisarius points out, your question as it stands is a bit v5-centric. The problem, however, still exists in current versions. As an example
Needs["Combinatorica`"]
ToCycles[{3, 4, 1, 2}]
works fine, while (after restarting the kernel),
Needs["Combinatorica`"]; ToCycles[{3, 4, 1, 2}]
fails with an error that
"ToCycles::shdw: Symbol ToCycles appears in multiple contexts {Combinatorica`,Global`}; definitions in context Combinatorica` may shadow or be shadowed by other definitions."
In Mathematica terms, the reason the one-liner doesn't work is that Mathematica tries to resolve all symbols in the line before evaluating Needs
(this was a surprise to me). This resolves ToCycles
to Global`ToCycles
(thus entering this symbol in the symbol table), before Needs
gets a chance to load the definition of Combinatorica`ToCycles
and add Combinatorica
to the $ContextPath. To make the one-liner work, you must use the full name of ToCyles
:
Needs["Combinatorica`"]; Combinatorica`ToCycles[{3, 4, 1, 2}]
To understand the error, you need to know that all Symbols in Mathematica have a full name of the form context`name
. A context is similar to a namespace in many other languages. Now, if a symbol (such as ToCycles
) is referenced without a context, Mathematica will look through the contexts currently in $ContextPath
and see if the symbol is defined in any of those contexts. If not, the symbol is resolved in the current context, $Context
which is Global
in normal use.
When you load a package, the symbols of that package are defined in a package context (e.g. Combinatorica
), and when the package is fully loaded this context is added to the $ContextPath
so that you can access the symbols by their short name.
Now, you can see what the error means: Since the Combinatorica
has not yet been loaded when the symbols are resolved, ToCycles
resolves to Global`ToCycles
. After the package loads, Mathematica helpfully checks that all short names are unique, and finds in this case that the short name ToCycles
is now defined in two contexts on $ContextPath
one thus "shadowing" the other. To refer to a specific of these symbols, you must use the full name, e.g. Combinatorica`ToCycles
.
To resolve a shadow conflict, simply Remove
the unwanted symbol:
Remove[Global`ToCycles]
Don't know how readable this was, but hope it helps a bit...
回答2:
You are supposed to put the Needs[]
call(s) at the top of a notebook in a separate block, or on the first isolated line of a package.m file.
The kernel reads the whole line and parses it, including deciding on the contexts for symbols, before beginning to evaluate it. To avoid problems, do not use semicolons. Put two newlines after every statement in a package.
Especially after the BeginPackage[]
and/or Needs[]
.
来源:https://stackoverflow.com/questions/4664091/package-import-problem-in-mathematica