Re: 표현식에서 변수의 범위를 이해하는 데 도움이 필요합니다.범위 지정은 다음과 같습니다. 현지의() 존재하는 경우 네임스페이스, 검색하지 않는 경우 여기() 존재하는 경우 네임스페이스, 검색하지 않는 경우 글로벌() 네임스페이스.(또한 때때로 현재 데이터 테이블의 열 이름도 확인합니다).
첫 번째 스크립트에서 수행하는 작업은 이름을 입력하는 것입니다. "x"n 로 여기() 값이 있는 네임스페이스 "변하기 쉬운" , 다음 이름을 입력 "익스프레스"n 로 여기() 값이 있는 네임스페이스 Write( "여기에 변수가 있습니다: " || x ) , 이름을 입력 "exprB"n 로 여기() 값이 있는 네임스페이스 Glue( dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" ), dt1 << 닫을 때( exprA ) ) .
마지막으로 당신은 평가 "exprB"n -- 그런 다음 JMP는 먼저 다음을 확인하여 이 이름을 확인하려고 시도합니다. 현지의() 네임스페이스(존재하지 않음), 여기() 네임스페이스를 찾고 이를 찾습니다. 따라서 에 저장된 표현식을 실행합니다. 범위 지정( "여기", "exprB" ) .
그런 다음 테이블을 로드하고 특급 창에 대한 닫는 스크립트로.
이것이 스크립트의 끝이므로 여기() 스크립트에 대해 생성된 네임스페이스가 삭제되고 메모리가 지워집니다.
테이블을 닫으면 리터럴을 찾습니다. 특급 닫는 스크립트로 위와 같이 이름의 범위를 지정하려고 시도합니다( 현지의() , 여기() , 글로벌() ), 이번에는 없습니다 여기() 네임스페이스가 없고 세 네임스페이스에서 이름을 찾을 수 없으므로 오류가 발생합니다.
일반적으로 다른 범위에서 실행될 표현식에 변수를 정적 값으로 추가하려면 다음 중 하나를 사용하십시오. 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은 실제로 그렇게 하지 않으며 유지 관리하는 것은 코더에게 달려 있습니다. 지속성과 범위가 필요합니다. 내부의 코드 <<닫을 때( ... ) 메시지는 이름이나 범위를 관리하지 않고 메시지를 생성한 스크립트와 완전히 별도의 컨텍스트에서 평가됩니다.
조금 헷갈릴 수 있으니 도움이 되셨으면 합니다!!
Re: 표현식에서 변수의 범위를 이해하는 데 도움이 필요합니다.Jordan, 감사합니다. 행동을 설명합니다. 실제 스크립트에는 OnClose 문에서 변수를 공유하는 많은 테이블이 있기 때문에 제안된 네임스페이스 방식이 마음에 듭니다.
다음 코드를 이해하는 데 도움을 줄 수 있습니까?
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)로컬은 이름을 로컬 변수로 해석합니다. 이것이 의미하는 바는 무엇입니까? 중괄호로 일부 변수를 정의해야 하는 이유는 무엇입니까? 목적은 무엇입니까? (스크립팅 인덱스와 문서 모두 그것에 대해 많이 말하지 않습니다).
Re: 표현식에서 변수의 범위를 지정하는 방법을 이해하는 데 도움이 필요합니다.짧은 답변 -- 이름이 외부에 덮어쓰이지 않도록 합니다. 현지의() 차단하다.
긴 답변:
내 기능의 경우 다음과 같이 작성합니다.
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 ) 어떤 이유로 기능을 수행하고 해당 대기 단계 동안 누군가 재정의하는 스크립트가 첨부된 테이블을 닫습니다. 본인 -- wait 문이 완료되면 본인 이제 다른 변수를 참조하고 혼돈이 발생합니다.
그만큼 현지의() 함수는 로컬 블록을 생성하고 첫 번째 인수(목록)에 정의된 변수는 다음과 같이 해당 블록에 로컬입니다.
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;여기서 나는 둘 다 재정의한다. ㅏ 그리고 비 로컬 블록 내부에 있지만 비 로컬 블록 외부는 영향을 받지 않습니다. ㅏ 이다.퍼팅 본인 지역 변수로 사용하는 것이 가장 안전한 접근 방식입니다.
식에서 변수의 범위를 지정하는 방법을 이해하는 데 도움이 필요합니다.모두들 안녕,
간단한 예제 스크립트가 있습니다. 누군가 여기에서 변수의 범위가 무엇이며 왜 다른 방식이 아닌 한 방식으로 작동하는지 설명할 수 있습니까?
초기 스크립트는 다음과 같습니다.
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;아이디어는 테이블을 열고 테이블이 닫힐 때 실행해야 하는 표현식을 제공한다는 것입니다. Expression은 스크립트의 일부 변수를 평가하고 변경합니다(이 예에서는 아님).
작성된 방식으로는 작동하지 않습니다. 아무 일도 일어나지 않지만 실제 스크립트에서는 참조를 찾을 수 없다고만 표시됩니다.
이제 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" );
질문: 왜 이런 방식으로 작동하고 초기 방식으로는 작동하지 않습니까? 나는 그것이 효과가 있어야한다고 보았다.
이 스크립트에서 전역 변수를 사용하는 것을 좋아하지 않습니다. 작동하게 하는 다른 방법이 있습니까?
고급 통계 모델링자동화 및 스크립팅소비자 및 시장 조사데이터 접근데이터 혼합 및 정리실험 설계대량 맞춤화품질 및 프로세스 엔지니어링