Shadow problem when Getting a package from a Palette action
My simple first Palette is suppose to:
- Append my packages Path to
$Path
ActionMenu["test",{"The Simple Packages Path":> AppendTo[$Path,开发者_如何学运维 ToFileName[{NotebookDirectory[], "02 Simple Packages"}]]}]
- Get my packages
ActionMenu["Load Packages", {"Get my package":> Get["myPackage`"]}]
- Place on the selected input cell (or on a new input cell), a given input expression, containing different place holders.
OpenerView[{"my Package", Button["construct", Paste[StandardForm@Defer@construct[Placeholder["description"],Placeholder["another description"]]]]}]
The problem is that I keep getting "shadow" messages when I click on the "get my package" action menu item. And I'm sure I'm not double loading the package intentionally. When I click on "construct", it writes Global`construct["description","another description"]
. But I'm sure I didn't define it before getting the package (I killed the kernel on my tests).
Do you know what is wrong?
(I use Get
on my packages, instead of Needs
, to ensure a clean start of the package context)
Also: do you know of a simpler way of doing the Paste[StandardForm@Defer...
that ensures both that the expression being paste isn't evaluated and that it goes into an input cell, even when there's no cell selected?
Ok, it seems that your problem is due to the interplay between parsing and interface creation. What you would like in this case is to delay the parsing of package symbols in your interface - constructing code (package symbols that you use in button action functions), from the interface - creation time, until the "press button" time (assuming that by that time, the package has been loaded). Here is one way to do it:
Column[{ActionMenu["Load Packages",
{"Get my package" :> Get["ANOVA`"]}],
OpenerView[{"ANOVA", Button["construct",
With[{sym = Symbol["ANOVA"]},
Paste[StandardForm@Defer@sym[Placeholder["DATA"]]]]]}]}]
What we did here is to use With
to inject the symbol into the code for the button function. But, at the time your interface code is parsed, we prevent the creation of the Global
symbol with this name - this is what happens otherwise, and this is what causes your problem.
EDIT
If you know for sure that you only use symbols (functions) from packages, and not from the Global'
context, here is a version that will be "protected" from this problem: it will Remove
the generated symbol if its context turns out to be Global'
- and thus pressing button before the package has been loaded would result merely in a warning message (I use the symbol package
to attach the message to - should be replaced by whatever is the name of your interface - making function):
package::noload = "Please load the package containing symbol `1`";
Column[{ActionMenu["Load Packages",
{"Get my package" :> Get["ANOVA`"]}],
OpenerView[{"ANOVA", Button["construct",
With[{sym = Symbol["ANOVA"]},
If[Context[sym] === "Global`",
Message[package::noload, Style[ToString[sym], Red]];
Remove[sym];,
(* else *)
Paste[StandardForm@Defer@sym[Placeholder["DATA"]]]]]]}]}]
Well, I don't have your package, so for testing I changed the action menu to get the ANOVA package:
ActionMenu["Load Packages", {"Get my package" :> Get["ANOVA`"]}]
ANOVA[{{1, 1}, {1, 2}, {2, 4}, {2, 3}}]
now works without a hitch. No complaints about shadowing. This suggests that the cause of your shadowing problem lies somewhere else. I noticed, though, that the word ANOVA
stays blue. This will be related to the problem you reported here.
精彩评论