<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />몇 년 전, 저는 속성 스타일 측정 시스템 분석을 위한 샘플링 계획을 자동으로 생성하는 스크립트를 작성하는 작업을 하고 있었습니다. 큰 문제에 부딪힐 때까지 모든 것이 순조롭게 진행되었습니다. 실행 시간에 부품 수가 선택된 경우 스크립트가 사용 중인 부품의 마스터 "합격/불합격" 목록을 생성하는 창을 표시하도록 하려면 어떻게 해야 할까요? 이제 여러분은 이미 이것을 하기 위한 쉬운 방법을 생각하고 있을 것입니다. 그러나 나는 여전히 내가 생각해낸 방법을 자랑스럽게 생각하며 이 블로그 게시물에서 공유할 것입니다.
JSL 스크립팅 인덱스의 프로그래밍 부분에는 겉보기에 무해해 보이는 두 항목인 Eval과 Parse가 숨겨져 있습니다. 이러한 함수를 통해 교활한 스크립터는 마치 코드 조각인 것처럼 문자열을 실행할 수 있습니다. 이렇게 할 수 있다는 것은 놀라운 의미를 내포하고 있습니다. 이렇게 하면 이전의 문제도 해결할 수 있습니다.
간단한 스크립트를 작성하여 자세히 살펴보겠습니다.
//섹션 1:
//한 부분에 대한 합격/불합격 기준을 얻습니다.
//일부 변수 초기화
나 = 1 ;
listParts = {} ;
// 기준을 얻기 위해 모달 창을 빌드합니다.
새창 ( "합격/불합격 목록 가져오기" ,
<< 모달 ,
H 목록 상자 (
V 목록 상자 (
라인업 상자 ( 2 ,
텍스트 상자 ( 숯 ( 나 )) , listParts [ 나 ] = 텍스트 편집 상자 ( "통과하다" ) ,
버튼 박스 ( "좋아요" , listParts [ 나 ] = listParts [ 나 ] << 텍스트 가져오기 ; ) , 버튼 박스 ( "취소" )
)
)
)
) ;
//목록 보기
보여주다 ( listParts [ 나 ]) ;
로그가 표시되는지 확인한 다음 이 스크립트를 실행하십시오. 스크립트 자체는 창을 표시하고 한 부분에 대해서만 해당 부분이 "합격"인지 "실패"인지 묻습니다. 확인 버튼을 누르면 창에 있는 모든 텍스트가 i로 전달됩니다. 일 listParts 목록의 위치 및 listParts가 로그에 표시됩니다. 단 하나의 항목 목록에 결과를 저장하는 것은 지금은 다소 어리석은 것처럼 보이지만 합격/불합격 기준을 저장할 부품이 둘 이상인 경우 의미가 있습니다. 3 부분에 대한 스크립트의 모양은 아래 예를 참조하십시오.
//섹션 2:
//위 스크립트를 반복하지만 세 부분에 대한 기준을 잡습니다.
나 = 1 ;
listParts = {} ;
새창 ( "합격/불합격 목록 가져오기" ,
<< 모달 ,
H 목록 상자 (
V 목록 상자 (
라인업 박스 ( 2 ,
텍스트 상자 ( 숯 ( 1 )) , listParts [ 1 ] = 텍스트 편집 상자 ( "통과하다" ) ,
텍스트 상자 ( 숯 ( 2 )) , listParts [ 2 ] = 텍스트 편집 상자 ( "통과하다" ) ,
텍스트 상자 ( 숯 ( 삼 )) , listParts [ 삼 ] = 텍스트 편집 상자 ( "통과하다" ) ,
버튼 박스 ( "좋아요" , ~을 위한 ( 나 = 1 , 나 <= 삼 , 나 ++, listParts [ 나 ] = listParts [ 나 ] << 텍스트 가져오기 ; )) , 버튼 박스 ( "취소" )
)
)
)
) ;
보여주다 ( listParts ) ;
그러나 아직 문제를 해결하지 못했습니다. 스크립트가 실행되기 시작할 때까지 알려지지 않고 스크립트가 실행될 때마다 다를 수 있는 일부 임의의 수의 부분을 기반으로 이 스크립트가 동적 수의 텍스트 상자를 표시하도록 하려면 어떻게 해야 합니까? 앞서 언급한 신동인 Eval과 Parse를 구출하세요. 다음 코드를 살펴보십시오.
//섹션 3:
//부품 수 결정
새창 ( "부품이 몇 개야?" ,
<< 모달 ,
코 = 숫자 편집 상자 ( 10 ) ,
버튼 박스 ( "좋아요" , numParts = 코 << 얻다 ; )
) ;
보여주다 ( numParts ) ;
listParts = {} ;
//모달 창에 대한 스크립트의 첫 번째 부분을 빌드합니다.
//" is \!"에 대한 이스케이프 문자 시퀀스
ㅏ = "
새 창(\!"합격/불합격 목록 가져오기\!",
<<모달,
H 목록 상자(
V 목록 상자(
라인업 상자( 2,
" ;
//for 루프는 두 번째 부분을 생성하여 부분이 있는 만큼 많은 입력 상자를 만듭니다.
// || 연결의 바로 가기입니다.
비 = "" ;
~을 위한 ( 나 = 1 , 나 <= numParts , 나 ++,
b1 = 숯 ( "텍스트 상자(문자(" || 숯 ( 나 ) || ")), listParts[" || 숯 ( 나 ) || "] = 텍스트 편집 상자(\!"통과\!")," ) ;
비 = 비 || b1 ;
) ;
//모달 창에 대한 스크립트의 마지막 부분을 빌드합니다.
씨 = "
Button Box(\!"OK\!", for (i = 1, i <=numParts, i++, listParts) = listParts << Get Text;)), Button Box(\!"Cancel\!")
)
)
)
)
" ;
//스크립트의 일부를 결합하고 실행
디 = ㅏ || 비 || 씨 ;
평가 ( 구문 분석 ( 디 )) ;
// 생성된 것을 확인
보여주다 ( 디 ) ;
보여주다 ( listParts ) ;
먼저 numParts에 저장된 부품이 몇 개인지 사용자에게 묻는 섹션이 있습니다. 다음으로 스크립트는 모두 보라색이라는 점을 제외하면 JSL처럼 의심스럽게 보이는 세 개의 개별 문자열을 생성합니다. 첫 번째 문자열은 텍스트 상자가 삽입된 부분까지 이전 스크립트의 정확한 복사본(따옴표 문자가 문자열을 끝내지 않도록 하는 일부 특수 코드 포함)입니다. 두 번째 부분은 이전에 많은 부분이 입력되었지만(numParts) 텍스트 상자 반복으로 구성된 문자열을 작성하는 for 루프입니다. 세 번째 섹션은 이전 스크립트의 마지막 부분입니다.
이 문자열이 생성되면 결합합니다( 디 = ㅏ || 비 || 씨 ; ), 그런 다음 평가 ( 구문 분석 ( 디 )) ; JMP가 문자열 d(텍스트 상자의 수를 조정할 수 있는 동적으로 생성된 문자열)를 문자열 d가 단순한 문자열이 아닌 JSL 스크립트인 것처럼 구문 분석할 때 어떤 일이 발생하는지 평가하는 명령입니다. 많은 텍스트 상자를 표시하는 매우 긴 명령과 생성된 통과/실패 목록을 모두 보려면 로그를 살펴보십시오(기본값을 수락하는 경우 아래에 표시됨).
디 = "
새 창(\!"합격/불합격 목록 가져오기\!",
<<모달,
H 목록 상자(
V 목록 상자(
라인업 상자( 2,
Text Box(char(1)), listParts[1] = 텍스트 편집 상자(\!"Pass\!"),Text Box(char(2)), listParts[2] = 텍스트 편집 상자(\!"Pass\ !"),Text Box(char(3)), listParts[3] = 텍스트 편집 상자(\!"Pass\!"),Text Box(char(4)), listParts[4] = 텍스트 편집 상자(\ !"Pass\!"),Text Box(char(5)), listParts[5] = 텍스트 편집 상자(\!"Pass\!"),Text Box(char(6)), listParts[6] = 텍스트 Edit Box(\!"Pass\!"),Text Box(char(7)), listParts[7] = Text Edit Box(\!"Pass\!"),Text Box(char(8)), listParts[ 8] = 텍스트 편집 상자(\!"Pass\!"), 텍스트 상자(char(9)), listParts[9] = 텍스트 편집 상자(\!"Pass\!"), 텍스트 상자(char(10) ), listParts[10] = 텍스트 편집 상자(\!"통과\!"),
Button Box(\!"OK\!", for (i = 1, i <=numParts, i++, listParts) = listParts << 텍스트 가져오기;)), 버튼 상자(\!"취소\!")
)
)
)
)
";
listParts = {"통과", "통과", "통과", "통과", "통과", "통과", "통과", "통과", "통과", "통과"};
여기에서 의미하는 바를 잠시 생각해 보십시오. 이러한 개념을 사용하면 자체적으로 조정된 다음 자체적으로 실행되는 코드를 만들 수 있습니다. 동적, 자기 참조, 재귀 및 미친 스크립트는 시작에 불과할 수 있습니다. 충분한 시간과 인내심이 주어지면 이 개념을 스카이넷을 만드는 데 사용할 수 있을 것입니다. 다시 생각해 보면 그다지 좋은 생각이 아닐 수도 있습니다…
Erin이 말해야 하는 것 외에도 이 예에서 항상 이름을 적절하게 사용하지 않는다는 점에서 내 부분의 약간의 어리석음으로 이것을 역추적할 수 있습니다. 내가 생각하는 것은 창이 생성될 때 많은 텍스트 상자가 생성된다는 것입니다. 텍스트 상자는 개체이므로 << Get Text() 메시지를 보낼 수 있어야 합니다. 어리석음(행운?)이 발생하는 곳은 각 텍스트 상자에 ListParts라는 이름이 할당된다는 것입니다. 언제 ListParts[x]에 Get Text() 메시지를 보내면 실제로 일부 텍스트를 받습니다. 돌이켜보면 listParts[x] 텍스트 상자에 다른 이름을 지정해야 했습니다(즉, 아래 예에서 ListParts[1]을 tb[1]로 대체).
Text Box(char(1)), listParts[1] = Text Edit Box("Pass"),
이것은 스크립트가 실제로는 틀렸음에도 불구하고 작성자가 원하는 것을 수행하는 드문 경우 중 하나의 예라고 생각합니다.
여기서 문제는 <<
객체가 아닌 것에 메시지를 보낼 수 없으며 목록은 데이터 테이블과 같은 의미에서 객체가 아닙니다. 나는 최근에 내가 시도했다는 것을 깨닫고 내 클라이언트의 추가 기능 중 하나에서 오랫동안 지속된 버그를 수정했습니다.
list<<INSERT item=""></INSERT>
대신에
insert item(list, item)
우리 중 많은 사람들이 혼란스러워하는 부분은 연관 배열이 <<메시지를 받을 수 있는 개체이므로 다음과 같이 동일한 이름을 가진 명령에 대해 다른 구문을 볼 수 있다는 것입니다.
map=associative array(:Name, :Weight);
map<<INSERT item=""></INSERT>
당면한 질문으로 돌아가서, 왜 예제가 처음에 listparts[i]<Re: 평가(), 구문 분석() 및 재귀, 메타 프로그래밍의 모험
좋은 예, 감사합니다 @Jed_Campbell .해결할 수 없는 문제가 하나 있습니다.다음 오류가 발생합니다. Send Expects Scriptable Object in access or evaluation of 'List' , {/*###*/"Pass", "Fail"}
문제를 일으키는 것은 이 보내기 명령이라고 생각합니다.1개 이상의 숫자를 선택하는 경우에만 오류가 발생합니다.이견있는 사람?
listParts = listParts << Get Text;