JMP 插件 — 使用命名空间隔离多个实例JMP社区的各位好,
我正在开发一个 JMP 插件,它可以创建窗口、存储全局变量并调用函数。单实例运行一切正常,但当用户启动插件两次时,两个实例共享同一个全局作用域,导致变量冲突(一个窗口的状态覆盖了另一个窗口的状态)。
我已将脚本初始化为默认名称为 here(1),甚至创建了自己的新空间 (ns = newspace()) 并将所有变量都放在其中,但仍然存在冲突。我知道窗口命名空间,但我也想避免窗口之外的变量发生冲突。
// Launch this script twice — second run breaks the first window
strLabel = "Instance A";
counter = 0;
win = New Window( "Test " || strLabel,
btn = Button Box( "Click me",
counter++;
btn << Set button name( strLabel || " clicked " || Char( counter ) || "x" );
)
);
自动化和脚本编写回复:JMP 插件——使用命名空间隔离多个实例如果每个窗口都是独立的,那么我建议使用专为此设计的窗口命名空间:
Names default to here(1):
// Functions outside the window are still accessible
rand = function({}, floor(random uniform(10)));
win = New Window("Values",
show toolbars(0), show menu(0),
// You can put statements above display elements
window:randomvalue = rand();
v list box(
text box("Enter a value for this box:"),
// All references to display elements should be in the window namespace
window:teb = text edit box(""),
// Examples reading and writing values.
button box("Update random value", window:randomvalue = rand() ),
button box("Get values from this window",
window:tb << Set Text(
"Random value: " || char(window:randomvalue) ||
"\!NEntered Value: " || (window:teb << Get Text)
)
),
window:tb = text box("")
)
);
// You can get to this from outside the window, but make sure this namespace is protected too - for example from inside another window.
show(win:randomvalue, win:teb << Get Text);
回复:JMP 插件——使用命名空间隔离多个实例最简单的选择是使用窗口命名空间。我认为第二简单的方法(如果忽略上下文框)是使用命名空间,前提是你可以给它们命名。再进一步,可以使用一个命名空间,并将值收集到列表/关联数组中,然后访问这些列表/关联数组。匿名命名空间应该也可以,但这需要一些额外的工作才能在窗口内访问正确的命名空间。
回复:JMP 插件——使用命名空间隔离多个实例您好,感谢您的回答。我会实现窗口命名空间,但是提取窗口外部变量的部分有点困难,因为如果我运行多个实例,窗口名称是相同的。
回复:JMP 插件——使用命名空间隔离多个实例这里有个小技巧:所有操作都直接从窗口调用,而不是先启动脚本,然后在运行过程中请求用户输入。即使你不需要立即输入用户信息,也可以打开一个显示“正在启动……”的窗口,然后在 `On Open()` 函数中,把窗口打开之前的所有代码都放到窗口打开之前,但使用窗口或局部作用域的变量。对于较长的脚本,这种方法可能会变得难以管理,这时你可以考虑将这些代码拆分成不同的函数,这些函数在窗口打开之前定义,甚至放在不同的文件中。
例如,时间序列过程数据插件的“验证列”就是这样编写的。请注意,在调用“新建窗口”之前,脚本第274 行定义了 UpdateUI(如果这给以后的读者造成了困扰,敬请谅解),然后在第 670 行按下按钮以及其他字段更新时调用它。
请注意,此函数在很多地方都调用了 `window` 变量——该函数的主要目的是更新用户界面。对于大多数插件,我不建议这样做,应该将所需的所有信息作为参数传递,然后在函数内部使用所有局部变量,并将结果仅返回给函数。
回复:JMP 插件——使用命名空间隔离多个实例如果你运行的是插件,那么直接使用这里的命名空间可能就完全没问题了。如果从同一个脚本窗口运行,则无法正常工作;但如果从不同的脚本窗口运行,则应该可以正常工作。