Re: 기본 로컬 대 로컬의 명시적 선언나는 명시적인 지역 선언 목록을 좋아합니다. 하나를 놓치면 전역 이름 공간에 도달하고 showglobals()가 이를 식별합니다.거품을 내고 헹구고 전체 공간이 깨끗해질 때까지 반복하십시오.
Re: 기본 로컬 대 로컬의 명시적 선언이것을 확인하기 위한 작업 흐름이 무엇인지 물어봐도 될까요? 개발 중에 함수 끝에 "Show Globals()"를 추가하고 전역 네임스페이스에 의도하지 않은 항목을 추가하지 않았는지 수동으로 확인합니까? 아니면 테스트를 통해 시행할 수 있는 것입니까?
추가 질문: 내가 사용해야 하는 전역 표시 또는 기호 표시입니까? 내 함수에서 로컬 변수를 의도적으로 생략한 경우에도 Show Globals의 출력이 표시되지 않지만 Show Symbols를 사용하면 출력이 너무 많아 새 목록이 표시되지 않습니다.
도움이 된다면 모든 스크립트 파일에서 "Names Default To Here" 모드를 켭니다.
Re: 기본 로컬 대 로컬의 명시적 선언과거의 내 작업 흐름은 Names Default To Here를 사용하지 않고 전역 네임스페이스를 명확하게 유지하는 것입니다. Show Globals()는 항상 Names Default To Here를 사용하고 있다면 아무것도 보지 못할 것입니다. Show Symbols()는 깊게 중첩된 함수에서 사용하는 경우 호출 스택을 통해 정보를 보고하기 때문에 노이즈가 많습니다. 다음은 여기로 기본 이름 지정 및 기호 표시를 사용하도록 재작업한 작업 흐름 예제입니다. 그대로 실행하면 새지 않습니다. 주석 행 17(g3)에 오류가 발생합니다. g3이 'here' 네임스페이스에 입력되기 때문입니다. 예제의 g2 사용은 보기 흉한 문제를 강조합니다. 기본 로컬 해당 문제를 해결하지만 지적한 문제를 추가합니다. 향후 프로젝트에서 기본 로컬로 다시 전환해 볼 수 있습니다. 나는 그것이 나에게 더 안전한 선택이라고 생각합니다. 나는 변수를 쓰기 전에 읽는 것보다 명시적 지역 변수에서 변수를 남겨둘 가능성이 더 높습니다.
나는 당신이 나보다 더 세밀한 테스트를 시도하고 있다고 생각합니다. 마지막에 (globals 또는 here) 만 테스트합니다. 모든 함수에서 네임스페이스 누출을 테스트해야 하는 경우 이러한 아이디어 중 일부를 사용할 수 있습니다.
// **** you will probably need to restart JMP to really understand each change you make. ****
xyzzy = "before names default to here"; // this goes into globals. If you run again it goes into 'here'.
Names Default To Here( 1 ); // takes effect when executed
New Namespace( // don't put the functions in the here namespace, keep them in appDemo.
"appDemo" // this keeps the here namespace free of voluminous function definitions.
);
appDemo:originalLeakState = Log Capture( Show Symbols() ); // remember the original state
appDemo:f1 = Function( {p1}, // parameter list
{
//g2, // <<<< comment this use f2's local
g3, // <<<< comment this to make a leak
g1}, // local list
Write( "\!ng2=", g2 );
g1 = 1; // very local to this function
g2 = 2; // not local, in this example it is local to f2, a bug if unintentional
g3 = 3; // not local, lands in the 'here'
);
appDemo:f2 = Function( {p2},
{g2},
g2 = 42; // this will be over written by f1
appDemo:f1( p2 );
);
appDemo:f2( "x" );
// if you call f1 from here, the here:g2 gets written
// g2 = 142;
// appDemo:f1( "x" );
// a test might look like this
If( Log Capture( Show Symbols() ) != appDemo:originalLeakState,
Write( "\!n=============leak report==============" );
Show Symbols();
Throw( "variable namespace leaks, see log!" );
,
Write( "\!n========= no change to symbols =======" );
If( Length( appDemo:originalLeakState ),
Write(
"\!n========= original leak state: =======",
appDemo:originalLeakState
)
);
);Re: 기본 로컬 대 로컬의 명시적 선언감사합니다. 매우 유용합니다! 새는 것이 없는지 확인하는 자동 검사를 작성하기 위해 여기에 작성한 내용 중 일부를 사용할 수 있어야 한다고 생각합니다.
Re: 기본 로컬 대 로컬의 명시적 선언또한 DEFAULT LOCAL에는 이상한 점이 있습니다.실제로 스크립트를 읽고 생성되는 변수에 대한 해석을 기반으로 로컬 할당을 생성합니다.이것을 망치는 몇 가지 이상의 방법이 있습니다. 사람들에게서 가장 자주 보는 것은 변수 이름을 동적으로 만들려고 할 때입니다.내가 말하고 싶은 것은 그다지 좋지 않으며 당신도 그것을 명시적으로 말할 수 없기 때문에 그것은 일종의 동일합니다.
Names default to here(1);
f = function({},
{DEFAULT LOCAL},
x = 14;
Eval(Parse("x"||char(x)||"=28"));//not that anyone should ever do this BUT ...
return(x);
);
f();
namespace("here"); // notice how x14 is in the here namespace
/*
New Namespace(
{
f = Function( {},
{Default Local},
x = 14;
Eval( Parse( "x" || Char( x ) || "=28" ) );
Return( x );
),
x14 = 28
}
)
/*Re: 기본 로컬 대 로컬의 명시적 선언미래의 독자를 위해 결국 모든 로컬이 명시적으로 선언되도록 하는 데 사용하는 테스트 도우미를 작성했습니다.
/*
* Test that `invocation` does not add any variables to the Here namespace. It is important that
* this test be run first, else whatever variables may leak will leak before running this test and
* so they will already be present in `hereVariablesBefore`.
*
* Example:
* someFunction1 = Function( {}, {}, leakedVar = 1);
* someFunction2 = Function( {}, {safeVar}, safeVar = 1);
* assertNoLeakedVariables( Function( {}, {}, someFunction1() ) ); // Fails
* assertNoLeakedVariables( Function( {}, {}, someFunction2() ) ); // Passes
*/
assertNoLeakedVariables = Function( {invocation},
{hereVariablesBefore, hereVariablesAfter},
Try(
// Declare both of these in advance, because otherwise the key `hereVariablesBefore` will not be
// present in `hereVariablesBefore` and it makes the assertion confusing.
hereVariablesBefore = .;
hereVariablesAfter = .;
hereVariablesBefore = Namespace( "here" ) << Get Keys;
invocation();
hereVariablesAfter = Namespace( "here" ) << Get Keys;
UT Assert( Expr( Length( hereVariablesBefore ) ), Length( hereVariablesAfter ) );
If( Length( hereVariablesBefore ) != Length( hereVariablesAfter ),
showLeakedVariableNames( hereVariablesBefore, hereVariablesAfter )
);
,
UT Assert( exception_msg, "" )
)
);Re: 기본 로컬 대 로컬의 명시적 선언이것은 저에게 꽤 자주 나타났습니다. 매우 실망스러울 수 있습니다.
이 스크립트는 이름을 방해합니다(이름은 함수의 로컬 범위를 벗어남).
Names Default to Here( 1 );
some expr = Expr(
a = 4;
b = 5;
g = 6;
);
f = Function( {input expr},
{Default Local},
Print( "running expr" );
input expr
);
f( Name Expr( some expr ) );
show( a, b, g )여기에 솔루션이 있지만 이 솔루션의 문제점은 기술적으로 두 개의 함수 호출(2개의 스택 항목으로 계산되므로 225 스택 제한에 더 빨리 도달함)이라는 것입니다.
Names Default to Here( 1 );
some expr = Expr(
a = 4;
b = 5;
g = 6;
Show( Eval List( {a, b, g} ) );
);
f = Function( {input expr},
{Default Local},
Print( "running expr" );
Eval( Eval Expr(
Local( {Default Local},
Expr( Name Expr( input expr ) )
)
) );
1
);
f( Name Expr( some expr ) );
show( a, b, g )"Default Local" 지시문이 구문 분석 시간 지시문이 아니라 실행 시간 플래그라면 좋겠지만 아마도 현재 발생하고 있는 것은 구문 분석 시간에 이름 확인이 수행되어 런타임 이름 조회 규칙이 문제가 되는 것입니다. .
기본 로컬 대 로컬의 명시적 선언안녕하세요, 함수의 로컬 범위와 관련하여 위험을 제한하는 최선의 방법을 이해하려고 합니다. 내 이해에서 함수 실행 내에서 Here 범위를 오염시킬 가능성을 제한하기 위한 옵션은 로컬 변수를 선언하거나 기본 로컬을 사용하는 것입니다. 그러나 이들 각각에는 몇 가지 문제가 있습니다.
기본 로컬:
- 참조 값은 컨텍스트에 따라 달라질 수 있습니다. 로컬로 정의되지 않은 이름은 Here then possible(Names Default To Here가 해제된 경우) Global then current 테이블로 대체되기 때문입니다. 문서에서 언급한 바와 같이 이는 값이 컨텍스트에 따라 달라지므로 동작을 덜 예측할 수 있음을 의미할 수 있습니다.
명시적 선언:
- 참조 값은 컨텍스트에 따라 다를 수 있습니다. 이름이 로컬 이름에서 선언되지 않은 경우 선언될 때까지 이름이 여전히 이 폴백 동작을 사용하기 때문입니다.
- 할당이 실수로 Here 범위로 유출될 수 있습니다. 즉, 지역적으로 의도된 이름이 지역 이름 선언에서 생략되면 주변 Here 범위를 오염시킵니다.
- 일반적으로 이 외부 범위 오염은 추적하기 어렵습니다.
- 예를 들어 "i"를 반복자로 사용하는 For에서 함수를 호출하고 해당 함수에도 i를 사용하는 For가 있고 이를 로컬로 선언하지 못하는 경우 외부 For 루프에 영향을 미칩니다. 이것은 명백한 프로그래머 오류이지만 만들기는 쉽고 디버깅하기는 어렵습니다.
내 생각에 이상적인 옵션은 "엄격한 로컬"과 같은 것을 선언할 수 있을 것입니다. 이 옵션은 항상 정규화되지 않은 이름(값을 할당하고 값을 참조할 때)을 로컬 및 주변 범위가 한정된 이름으로만 액세스할 수 있기 때문에 취급합니다. 이렇게 하면 주변 스코프를 오염시킬 위험이 없을 뿐만 아니라 해당 스코프에 의존할 때 선언하도록 강요하여 주변 스코프의 로컬 오염을 제한할 수 있습니다.
고급 통계 모델링소비자 및 시장 조사데이터 접근데이터 탐색 및 시각화대량 맞춤화Re: 기본 로컬 vs 명시적 로컬 선언"워크플로"와 관련하여 #NamespaceInspector와 같은 작은 도우미는 변수를 추적하는 데 많은 도움이 됩니다.
이것들은 여기 네임스페이스에 표시되나요? 아니면 로컬 네임스페이스에 표시되나요?
디버깅이 완료되면 AddIn으로 업로드하겠습니다.