Programming/TclTk

TCL 순서제어 명령

Hunveloper 2022. 9. 2. 14:06
728x90

순서제어 명령

  • 루프를 위한 명령으로 while, foreach, for가 있음
  • 조건문으로 if와 switch가 있음
  • 에러 처리 명령으로 catch
  • 순서를 제어하기 위한 명령으로 break, continue, return, error가 존재
  • 몸체 부분은 치환을 방지하기 위해 { }로 묶어야 함
  • 마지막에 수행한 명령의 리턴값을 돌려줌
  • { }의 다른 용도는 Newline 문자를 포함한 스트링을 묶을 수 있음
  • if, for while 등의 명령은 참/거짓을 돌려주는 boolean 수식을 포함
  • if, for, while 명령은 내부적으로 expr 명령을 자동으로 수행하기에 명시하지 않아도 됨

If Then Else

  • if는 기본적인 조건 명령
  • 조건이 참이면 뒤에 따르는 body를 실행하고 그렇지 않으면 else를 실행
if boolean then body else body2
  • then과 else 키워드는 옵션이므로 사용하지 않아도 됨
if {$x == 0} {
    puts stderr "Divide by zero!"
}
else {
    set slope [expr $y/$x]
}
  • Newline 문자는 한 명령의 끝을 나타내지만 grouping 되어 있는 경우는 예외
  • elseif 명령은 이어진 조건문을 구성하는 데 사용
if {$key < 0} {
    incr range 1
} elseif {$key == 0} {
    return $range
} else {
    incr range -1
}

Switch

  • 수식에 값에 따라 어떤 특정 body를 수행하게 하는 데 사용
  • 조건은 간단한 비교문에서 패턴 매칭까지 다양하게 사용 가능
switch flags value pat1 body1 pat2 body2 ...
switch flags value { pat1 body1 pat2 body2 ... }
  • flags에 사용할 수 있는 값
    • -exact : 정확하게 일치하는 패턴만을 찾아냄
    • -glob : glob 형태의 패턴 매칭을 수행
    • -regexp : regular expression 패턴 매칭을 수행
    • -- : 플래그를 사용하지 않거나 플래그 부분의 마지막을 의미
  • 패턴과 몸체 부분을 하나의 인자로 묶는 방법
switch -exact -- $value {
    foo {doFoo; incr count(foo)}
    bar {doBar; return $count(foo) }
    default {incr count(other) }
}
  • default는 모든 switch문이 동작하지 않을 경우에 실행됨
  • grouping을 하지 않을 경우 역슬래쉬 치환을 사용
switch -glob -- $value \
    ^$key {body1} \
    \t### {body2} \
    {[0-9]*} {body3}
  • 치환을 허용하면서 Newline 문자를 허용하기 위해 “ “을 사용
switch -glob -- $value "
    $(key)* {puts stdout \"Key is $value\"}
    X* -
    Y* - {takeXorYaction $value }
"
  • 몸체 부분에 -를 쓰면 다음 패턴의 몸체 부분을 수행하게 됨

foreach

  • foreach 명령은 리스트에 있는 모든 값들을 변수에 대입해 가며 body를 반복 수행
foreach loopVar valueList commandBody
  • valueList 부분에 직접 리스트를 넣을 수 있다
set i 1
foreach value {1 3 5 7 11 13 17 19 23} {
    set i [expr $i*$value]
}
puts $i

#111546435

while

  • while 명령은 boolean 부분과 body 부분의 두 인자를 가짐
while booleanExpr body
  • while 명령은 반복적으로 booleanExpr 부분을 검사해 참인 경우에 body 부분을 반복 수행
  • while을 쓸 때 치환이 잘못 일어나는 경우가 없도록 주의
#bad
set i 0; while $i<10 {incr i}

#good
set i 0; while {$i<10} {incr i}

for

  • for 명령은 C의 for 명령과 유사
for initial test final body
  • initial은 루프가 돌기 이전에 수행할 초기화 부분
  • test는 루프의 반복 여부를 결정하기 위한 조건
  • final은 루프의 수행이 끝난 후에 수행할 명령
for {set i 0} {$i<10} {incr i 3} {
    lappend aList $i
}
puts $aList

#0 3 6 9

break와 continue

  • break 명령은 현재 수행 중인 루프에서 빠져나감
  • continue는 다음 루프를 즉시 수행

catch

  • catch 명령은 명령 수행 중 발생한 오류를 잡아 내기 위해 사용
catch command ?resultVar?
  • command는 수행할 body 부분
  • 두 번째 인자는 명령 수행의 결과나 오류 메시지를 저장할 변수의 이름
  • catch 명령은 오류없이 수행된 경우 0을 리턴, 오류가 발생한 경우는 1을 리턴
if [catch {
    command1
    command2
    command3
} result] {
    global errorInfo
    puts stderr $result
    puts stderr "*** TCL TRACE ***"
    puts stderr $errorInfo
} else {
    #comment
}

error

  • error은 catch로 잡아내지 않는 경우 스크립트를 종료시키는 오류를 임의로 발생
error message ?info? ?code?
  • message는 catch 명령에게 전달될 에러 메시지
  • info는 errorInfo 전역 변수에 넣을 값
  • 보통 errorInfo는 보통 에러가 발생한 위치에서의 스택의 상태를 수집하기 위해 사용
  • info 인자를 설정하기 않으면 error 명령 수행 상태가 errorInfo에 들어감
proc foo {} {
    error bogus
}
foo

#bogus
#    while executing
#"error bogus"
#    (procedure "foo" line 2)
#    invoked from within
#"foo"

return

  • return 명령은 프로시져를 수행 중간에 종료하거나, 프로시져로부터 종료하기 위해 사용

 

728x90
728x90