从Palette操作获取包时出现阴影问题

P. *_*eca 6 wolfram-mathematica

我简单的第一个调色板假设:

  • 将我的包路径附加到 $Path

ActionMenu["test",{"The Simple Packages Path":> AppendTo[$Path, ToFileName[{NotebookDirectory[], "02 Simple Packages"}]]}]

  • 拿我的包裹

ActionMenu["Load Packages", {"Get my package":> Get["myPackage`"]}]

  • 放置在所选输入单元格(或新输入单元格)上,给定输入表达式,包含不同的占位符.

OpenerView[{"my Package", Button["construct", Paste[StandardForm@Defer@construct[Placeholder["description"],Placeholder["another description"]]]]}]

问题是当我点击"获取我的包"动作菜单项时,我不断收到"影子"消息.我确信我不是故意加载包装的.当我点击"构造"时,它写道Global`construct["description","another description"].但是我确定在获得包之前我没有定义它(我在测试中杀死了内核).

你知道什么是错的吗?

(我Get在我的包上使用,而不是Needs,以确保包上下文的干净启动)

另外:你知道一种更简单的方法Paste[StandardForm@Defer...吗,即使没有选择单元格,也可以确保不评估粘贴表达式并进入输入单元格?

Leo*_*rin 6

好吧,您的问题似乎是由于解析和界面创建之间的相互作用.在这种情况下你想要的是延迟解析你的界面中的包符号 - 构建代码(你在按钮动作函数中使用的包符号),从界面创建时间到"按下按钮"时间(假设到那个时候,包已经加载了).这是一种方法:

Column[{ActionMenu["Load Packages",
   {"Get my package" :> Get["ANOVA`"]}],
   OpenerView[{"ANOVA", Button["construct",
       With[{sym = Symbol["ANOVA"]},
         Paste[StandardForm@Defer@sym[Placeholder["DATA"]]]]]}]}]
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是用于With将符号注入到按钮功能的代码中.但是,在解析接口代码时,我们会阻止Global使用此名称创建符号 - 否则会发生这种情况,这就是导致问题的原因.

编辑

如果您确定只使用包中的符号(函数)而不是Global'上下文中的符号(函数),则这个版本将受到"保护"以防止此问题:Remove如果生成的符号的上下文证明是Global'- 并且因此在加载包之前按下按钮将仅导致警告消息(我使用符号package将消息附加到 - 应该用接口的名称替换 - 制作功能):

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"]]]]]]}]}]
Run Code Online (Sandbox Code Playgroud)