eval — Tcl 스크립트 평가하기

eval — Tcl 스크립트 평가하기

스크립트 조각을 변수에 저장해 두고, 나중에 추가 값을 붙여 실행하고 싶을 때가 있어요. Tcl의 eval 명령은 여러 인자를 하나로 이어 붙여 완성된 스크립트로 만들어 재귀적으로 평가해 주는 명령이에요.

출처: Tcl 공식 문서 — eval

본문

시그니처

eval arg ?arg ...?

설명

eval은 하나 이상의 인자를 받아요. 이 인자들이 함께 하나 이상의 명령을 담은 Tcl 스크립트를 이뤄요. evalconcat 명령과 같은 방식으로 모든 인자를 이어 붙여, 그 이어붙인 문자열을 Tcl 인터프리터에 재귀적으로 넘기고 그 평가의 결과(또는 그것이 만든 에러)를 반환해요. list 명령은 단어 시퀀스를 eval 명령이 더 확장하지 않도록 인용한다는 점에 주의하세요.

예제

스크립트 조각을 변수에 저장해 두고, 나중에 추가 값을 붙여 실행하는 기법이에요. 이 기법은 Tcl 코어 곳곳(예: fcopy, lsort, trace 명령 콜백)에서 쓰여요:

set script {
 puts "logging now"
 lappend $myCurrentLogVar
}
set myCurrentLogVar log1
# Set up a switch of logging variable part way through!
after 20000 set myCurrentLogVar log2

for {set i 0} {$i<10} {incr i} {
 # Introduce a random delay
 after [expr {int(5000 * rand())}]
 update ;# Check for the asynch log switch
 eval $script $i [clock clicks]
}

가장 흔한 경우(스크립트 조각이 실제로 명령 프리픽스를 이루는 단어 목록일 때)에는 이런 호출 패턴에 {*}$script를 쓰는 게 더 좋아요. eval 명령보다 덜 일반적이라 실제로 더 견고하게 만들기 쉬워요.

lappend와 비슷하되 인자 값을 목록의 시작에 넣는 프로시저예요:

proc lprepend {varName args} {
 upvar 1 $varName var
 # Ensure that the variable exists and contains a list
 lappend var
 # Now we insert all the arguments in one go
 set var [eval [list linsert $var 0] $args]
}

다만 마지막 줄은 이제 eval 없이 이렇게 쓰는 게 일반적이에요:

set var [linsert $var 0 {*}$args]

더 알아보기

  • catch, concat, error, errorCode, errorInfo, interp, list, namespace, subst, uplevel
  • 키워드: concatenate, evaluate, script