回复:JSL 函数中的变量行为gzmorgan,感谢您的洞察力。 当前的 window() 解决方案看起来可能是最简单的解决方案,但它对我不起作用……至少,不是我尝试编写代码的方式。 我尝试对大多数变量主要使用 eval sub() 命令,这有效,但不适用于 nw(我的新窗口变量)或 _cw 用于当前窗口。 我可能只是错过了什么,但没关系。
我最终回到了您的另一个建议,即 Vince 之前提出的 window 命名空间。 到目前为止,我还没有遇到任何问题。
关于applicaiton builder,我知道但没用过。 我通常只编写自己的 GUI 和函数,然后手动创建插件。 我很难理解 set 函数和 this(或 self)以及什么叫什么,但我想我现在明白了...... 我会仔细看看。
感谢大家的投入。 我真的很感激不同的方法/建议。 我的脚本采用一组相关参数并以几种不同的方式绘制它们,但是设置它并手动单击参数然后导出它需要几分钟时间。 通过这些更新,并从主文件循环,我可以从单独的调用脚本而不是 GUI 调用脚本,并让它生成 N 个图而不是一组图。 过去需要几个小时……现在是十秒钟。当然,我花了很长时间才来到这里,但我可以重复使用它多年。
回复:JSL 函数中的变量行为哎呀!忘记提及,除了“this”和窗口命名空间之外,您还可以只引用当前窗口。我附上了备用脚本,
回复:JSL 函数中的变量行为我打算建议使用 Window 命名空间,这是一个很好的建议。我通常不使用 UI 窗口的功能。另一种引用本地对象的方法是使用 Set 函数并获取其句柄。 脚本如下。我使用了更简单的打印语句。您可能想要探索 App 开发器的使用,了解它的工作原理需要花费一些资金,但它非常方便。
names default to here(1);
myFun = Function({A, Z},{Default Local},
A[2] = 10;
B = 2*A;
show (A);
show(B);
show(Z);
nw = new window("test",
vlistbox(
textbox(Z),
textbox(char(B)),
buttonbox("Show array B (works)",
<<SET function=""></SET>回复:JSL 函数中的变量行为谢谢文斯。 我不知道窗口名称空间。 这可能会奏效,我会试试的。
现在我已经将我的 GUI 部分放在一个文件中,我打算将变量传递给我将称之为 main 函数的部分。 我要么从插件工具栏调用 GUI,要么运行一个小的自定义脚本,该脚本将循环 N 次,为 N 组输入参数调用主脚本。 可重用性在这里可能是一个问题,但覆盖变量可能无关紧要...... 我会看看进展如何。 感谢您的帮助。
回复:JSL 函数中的变量行为如果您使用全局变量或全局命名空间,问题是可重用性(您可能不关心)。
如果您使用两个不同的按钮运行 myFun 两次(假设您希望能够将您的窗口沙盒化并运行它的两个实例)。您将发生碰撞,第二次调用将覆盖第一次调用。
见下文。
names default to here(1);
new namespace("test");
test:myFun = Function({A1, Z1},{Default Local},
test:A = A1;
test:Z = Z1;
test:A[2] = 10;
test:B = 2*test:A;
show(test:A);
show(test:B);
show(test:Z);
//::g_b = b;
//::g_z = z;
test:nw = new window("test",
vlistbox(
textbox(test:Z),
textbox(char(test:B)),
buttonbox("Show array B (works)",
show(test:B)
),
buttonbox("Show string Z (works)",
show(test:Z)
),
buttonbox("show and close (works)",
show(test:Z, test:B); test:nw << closewindow())
)
)
);
x = [2,3];
y ="string";
test:myFun(x,y);
test:myFun([12, 14], "something else");
如果您使用命名空间,我建议使用 window 命名空间。 当窗口消失时它会自动删除,并且两个相同的窗口之间不会发生碰撞。
names default to here(1);
myFun = Function({A1, Z1},{DEFAULT LOCAL},
A = A1;
Z = Z1;
A[2] = 10;
B = 2*A;
show(A);
show(B);
show(Z);
//::g_b = b;
//::g_z = z;
nw = new window("test",
window:B = B; //uses the builtin window namespace
window:Z = Z; //works because this is a glue statement that returns the last thing
window:box = vlistbox( //which in this case is the vlistbox
textbox(window:Z),
textbox(char(window:B)),
buttonbox("Show array B (works)",
show(window:B)
),
buttonbox("Show string Z (works)",
show(window:Z)
),
buttonbox("show and close (works)",
show(window:Z, window:B); window:box << closewindow())
)
);
);
x = [2,3];
y ="string";
myFun(x,y);
myFun([12, 14], "something else");回复:JSL 函数中的变量行为谢谢文斯。 我没想到 eval(substitute(expr()))。 对于我的一些更复杂的脚本,我认为跟踪被替换的内容和位置可能太难了。 我的代码组织得不太好,调试起来很困难。回复:JSL 函数中的变量行为谢谢,你的全局想法给了我另一个想法。我不太介意变量是全局的这一事实,但如果它们确实需要是全局的,我宁愿将它们限定在一个包含的命名空间中。
我不认为 clear globals() 命令会在这里咬我,但它让我有了我的召回函数(我的全局召回变量被另一个使用 clear globals() 的脚本清除了)。我给 JMP 发了邮件,他们提出了两种选择:通过锁定全局变量或将它们放在自己的命名空间中来保护全局变量。 命名空间实际上在健壮性方面更直接。
无论如何,下面更新的代码似乎工作正常。 缺点是每次我引用一个变量时都要额外输入“test:”。 我意识到我可能不需要为脚本中的每个变量使用它,但另一方面,这可能是一种很好的做法,因为这种特殊用途是全局命名空间,我可以通过将光标悬停在变量名称上来查看变量内容。
注意 A1 和 Z1 的使用。 它没有让我分配给 test:A 和 test:Z。
错误:参数应该在“Function”的访问或评估中列出,Function/*###*/({test:A, test:Z}, .....
我会看看是否可以处理多个文件。
new namespace("test");
test:myFun = Function({A1, Z1},{Default Local},
test:A = A1;
test:Z = Z1;
test:A[2] = 10;
test:B = 2*test:A;
show(test:A);
show(test:B);
show(test:Z);
//::g_b = b;
//::g_z = z;
test:nw = new window("test",
vlistbox(
textbox(test:Z),
textbox(char(test:B)),
buttonbox("Show array B (works)",
show(test:B)
),
buttonbox("Show string Z (works)",
show(test:Z)
),
buttonbox("show and close (works)",
show(test:Z, test:B); test:nw << closewindow())
)
)
);
test:x = [2,3];
test:y ="string";
test:myFun(x,y);回复:JSL 函数中的变量行为我不得不求助于设置全局变量来完成这项工作。似乎对话框代码无法正确看到变量。这不是一个很好的解决方案,因为它违背了在函数中使用局部变量的目的。
names default to here(1);
myFun = Function({A, Z},{Default Local},
A[2] = 10;
B = 2*A;
show(A);
show(B);
show(Z);
::g_b = b;
::g_z = z;
::g_nw = new window("test",
vlistbox(
textbox(Z),
textbox(char(B)),
buttonbox("Show array B (works)",
show(::g_B)
),
buttonbox("Show string Z (does not work)",
show(::g_Z)
),
buttonbox("show and close (does not work)",
show(::g_Z, ::g_B); ::g_nw << closewindow())
)
)
);
x = [2,3];
y ="string";
myFun(x,y);回复:JSL 函数中的变量行为B甚至没有为我工作。
这通常是我做 GUI 东西的方式。对于您给出的示例来说,它过于复杂,但我认为它显示了几种不同的方法。
names default to here(1);
myFun = Function({A, Z},{Default Local},
A[2] = 10;
B = 2*A;
Eval(
Substitute(
Expr(
nw = new window("test",
vlistbox(
textbox(char(DV_Z)),
textbox(char(DV_B)),
buttonbox("Show array B (works)",
show([]||DV_B); //otherwise you run into an invalid matrix token
),
buttonbox("Show string Z (does not work)",
//show([]||DV_Z); //shouldn't work, you can't make a string a matrix
show(DV_Z);
//or
show(list(DV_Z));
),
buttonbox("show and close (does not work)",
<<SET function=""></SET>JSL 函数中的变量行为
我的脚本通常有两个主要组件:一个主函数,后跟 GUI 代码,所有这些都在同一个文件中。 我通常使用 Here 命名空间中包含的变量,从用户输入中获取变量,然后从“确定”按钮框中调用主函数。 我不向主函数传递任何变量,而只使用在“确定”按钮框脚本上分配的变量。 我正在考虑更改至少一个脚本,以便第一个文件具有 GUI,第二个文件具有主要功能。 在执行此操作之前,我将检查它在一个 JSL 文件中的工作原理。 下面是一个精简的示例,绕过 GUI,仅在定义函数之后但调用之前定义变量。
我注意到的一件事是,脚本运行后很难调试,因为当我将鼠标悬停在 x 和 y 上时,我可以看到窗口底部状态栏中的内容。 但对于局部变量 A、B、Z 和 nw 来说情况并非如此。 我想知道是否有人对此有任何提示。
我也不确定如何从按钮框脚本访问变量内容。 如果运行下面的代码,您可以看到 A、B、Z 按预期显示在日志中(在创建新窗口之前),并且 B 和 Z 也显示在新窗口文本框中,但是按钮box 脚本无法直接访问这些变量。 我能够使用 eval(parse(eval insert())) 来获取数组 B,但我无法获取字符串 Z。有没有更直接的方法可以让它发挥作用?
names default to here(1);
myFun = Function({A, Z},{Default Local},
A[2] = 10;
B = 2*A;
show (A);
show(B);
show(Z);
nw = new window("test",
vlistbox(
textbox(Z),
textbox(char(B)),
buttonbox("Show array B (works)",
show(parse(Eval(Parse(Eval Insert(
"\[^"char(B)"^]\"
)))))
),
buttonbox("Show string Z (does not work)",
show(Eval(Parse(Eval Insert(
"\[^"char(Z)"^]\"
))))
),
buttonbox("show and close (does not work)", show(Z, B); nw << closewindow())
)
)
);
x = [2,3];
y="string";
myFun(x,y);
谢谢,
麦克风
自动化和脚本编写质量和工艺工程