回复:需要帮助了解变量在表达式中的作用域范围界定是这样的——查找当地的()命名空间(如果存在),如果不存在则在这里()命名空间(如果存在),如果不存在则在全球的()命名空间。(此外,它有时也会检查当前数据表的列名)。
您在第一个脚本中所做的是输入名称"x"n进入这里()有值的命名空间“多变的” , 然后把名字"exprA"n进入这里()有值的命名空间写(“这里是变量:” || x ) ,然后输入名称"exprB"n进入这里()有值的命名空间胶水(dt1 = 打开(“$SAMPLE_DATA/Big Class.jmp”),dt1 << 关闭时(exprA)) .
最后你评估"exprB"n -- JMP 然后尝试通过首先检查当地的()命名空间(它不存在),然后这里()命名空间并找到它——因此它运行存储在As Scoped( "这里", "exprB" ) .
然后加载表格并放置exprA作为窗口的关闭脚本。
由于这是脚本的结尾,那么这里()为脚本创建的命名空间被删除并清除内存。
当您关闭表格时,它会找到文字exprA作为结束脚本,然后它会尝试按上述方式定义名称(在当地的() ,这里() ,全球的() ),只是这次没有这里()命名空间,它在三个命名空间中的任何一个中都找不到该名称,从而引发错误。
通常,当您要将变量作为静态值添加到将在不同范围内运行的表达式时,请使用Eval( Eval Expr( ...; Expr( 名称 Expr( val ) ); ... ) )或其他等价物。
根据我的个人经验,我为每个脚本(匿名)创建显式命名空间,然后手动将所有变量范围限定为相应的命名空间。然后我可以根据需要传递这个命名空间(当然,当脚本完成/窗口关闭时,我会清除并关闭命名空间)。
以下是如何使您的脚本工作的一些示例:
Names Default To Here( 1 );
x = "Variable";
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose( Write( "\!NHere is variable: " || Expr( x ) ) );
) );
或者
Names Default To Here( 1 );
x = "Variable";
exprA = Expr(
Write( "\!NHere is variable: " || x )
);
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose( x = "rather"; Expr( Name Expr( exprA ) ) );
) );
或者
Names Default To Here( 1 );
self = New Namespace();
self:x = "Variable";
self:exprA = Expr(
Write( "\!NHere is variable: " || self:x )
);
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose(
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)
);
) );请注意,虽然许多编程语言创建本地命名空间并使用引用计数器保留它们直到不再需要它们(例如带有函数的 Python 等),但 JSL 并没有真正做到这一点,而是由编码器来维护任何需要持久性和范围界定。 里面的代码<<关闭时(...) message 在完全独立于创建它的脚本的上下文中进行评估,没有名称或范围的管理。
希望这会有所帮助,这可能有点令人困惑!
回复:需要帮助了解变量在表达式中的作用域乔丹,非常感谢,它确实解释了这种行为。 我确实喜欢您提出的使用名称空间的方法,因为真正的脚本有许多表会在它们的 OnClose 语句中共享变量。
你能帮我理解下面这段代码吗:
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)Local 将名称解析为局部变量,这是什么意思? 为什么需要在大括号中定义一些变量,目的是什么? (脚本索引和文档都没有说太多)。
回复:需要帮助理解变量在表达式中的作用域简短的回答——它可以防止名称覆盖范围之外的任何内容当地的()堵塞。
长答案:
对于我的函数,我这样写:
some function = Function( {arg1, arg2, etc},
{Default Local},
self:arg1 = arg1;
self:arg2 = arg2;
//do something amazing!
//call a method:
self:call method
);
call method = Function( {},
//do something else amazing!
1
)
然后我使用元编程来定义自己并为每个函数注入一个引用,将其转换为类似以下内容:
self:some function = Function( {arg1, arg2, etc},
{Default Local},
self = Namespace( "#48" );
self:arg1 = arg1;
self:arg2 = arg2;
//do something amazing!
//call a method:
self:call method
);
self:call method = Function( {},
{self},
self = Namespace( "#48" );
//do something else amazing!
1
)这创建了一些与 Python 类非常相似的东西(我的代码与上面的语句有很大不同,但概念上相似)。我不想发生的事情是有参考自己被任何其他值覆盖。
想象一下,在一个函数中,我有一个等等( 1 )出于某种原因起作用,并且在该等待阶段有人关闭了一个表,该表附有重新定义的脚本自己-- 当等待语句完成时自己现在指的是不同的变量,随之而来的是混乱。
这当地的()函数创建一个本地块,第一个参数(列表)中定义的任何变量都是该块的本地变量,例如
Names Default to Here( 1 );
a = 1;
b = 4;
Print( "Before Local Block:" );
Show( a, b );
Local(
{local_var1, local_var2, b},
local_var1 = 4;
local_var2 = 2;
b = 9;
Print( "Inside Local Block:" );
Show( local_var1, local_var2, a, b );
a = 5;
);
Print( "After Local Block:" );
Show( Try( local_var1, Empty() ), Try( local_var2, Empty() ), a, b )
/*:
"Before Local Block:"
a = 1;
b = 4;
"Inside Local Block:"
local_var1 = 4;
local_var2 = 2;
a = 1;
b = 9;
"After Local Block:"
Try(local_var1, Empty()) = Empty();
Try(local_var2, Empty()) = Empty();
a = 5;
b = 4;这里我重新定义两者A和b在本地块内,但是b本地块外不受影响,而A是。推杆自己作为局部变量是最安全的方法。
需要帮助理解变量在表达式中的作用域大家好,
我有一个简单的示例脚本。 有人可以解释一下这里变量的范围是什么以及为什么它以一种方式而不是另一种方式工作?
这是初始脚本:
Names default to here(1);
Clear Globals();
x="Variable";
exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;我的想法是,我打开表并给它一个关闭时需要运行的表达式。 表达式计算并更改(不在本例中)脚本中的一些变量。
它的编写方式不起作用 - 什么也没有发生,但在我的真实脚本中它只是说它找不到参考。
好吧,让我们尝试使 ExprA 成为全局的:
Names default to here(1);
Clear Globals();
x="Variable";
::exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;现在它确实看到了表达式,但仍然不起作用,因为现在它看不到 x 变量。
好吧,让我们也将 x 设为全局:
Names default to here(1);
Clear Globals();
::x="Variable";
::exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;现在它可以工作了:
Scriptable[]Here is variable: Variable
// Close Data Table: Big Class
Close( "Big Class" );
问题是:为什么它会以这种方式工作,而不能以最初的方式工作? 我看了一下,应该有用。
我不喜欢在这个脚本中使用全局变量 - 还有其他方法让它工作吗?
高级统计建模自动化和脚本编写消费者和市场研究数据存取数据混合和清理实验设计大规模定制质量和工艺工程