回复:需要幫助了解變量在表達式中的作用域範圍界定是這樣的——查找當地的()命名空間(如果存在),如果不存在則在這裡()命名空間(如果存在),如果不存在則在全球的()命名空間。(此外,它有時也會檢查當前數據表的列名)。
您在第一個腳本中所做的是輸入名稱"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" );
問題是:為什麼它會以這種方式工作,而不能以最初的方式工作? 我看了一下,應該有用。
我不喜歡在這個腳本中使用全局變量 - 還有其他方法讓它工作嗎?
高級統計建模自動化和腳本編寫消費者和市場研究數據存取數據混合和清理實驗設計大規模定制質量和工藝工程